iconv()による文字コード変換
hykw
hykw
ATOMRSS
  • codeなにがしブックマークに追加する 0 users
  • このページを del.icio.us に追加
  • このページをはてなブックマークに追加
  • GoodJob
  • 2

GJGJ

説明

C言語で iconv により文字コードを変換する例です。

探してみると意外と見つからないので登録しておきます。

ソースコード

コメント

これはひどいタグが付いちゃってますね(^ ^;)
ちょっと理解しずらいコードかもしれません。
コメント無いし。

以下のページも参考に...
http://www.linux.or.jp/JM/html/LDP_man-pages/man3/iconv.3...

  • GoodJob
  • 0

  • ゲスト
  • 3:ゲスト (うーん)
  • 2007/08/02 04:37

使いかたのサンプルなんでエラーチェックとかを多少省くのはいいのかもしれませんが、iconv_closeの前にiconv(cd, NULL, NULL, &pout, &olen)しておかないと出力エンコーディングがstatefulな場合 (iso-2022-jpとか) にstateを元に戻すシーケンスが出力されないのではないでしょうか。

  • GoodJob
  • 0

  • hykw
  • 4:hykw
  • 2007/08/02 07:50

コメントありがとうございます。
実は(C言語から) iconv(3) ってほとんど使った事無い上に、検索してもそのままズバリの使い方が見つからないので、見よう見まねで書いたんです(^^;


どなたか、よろしければ「俺ならこう書く」して頂けると助かるのですが w

  • GoodJob
  • 0

  • ゲスト
  • 5:ゲスト
  • 2007/08/02 20:43

iconv(1) の実装を見るのが iconv(3) の使い方の一番良いサンプルでしょう……と言おうと思って実際に libiconv の実装を見てみたら、そうでもなかった。困ったことだ。
あまり良い API じゃないんだよね、iconv って……

  • GoodJob
  • 0

>5: ゲストさん 
時代はICUっすねw 

で、いきなりえらそうな事を言ってしまったので 
責任もって「俺ならこう書く」を投稿させていただきますm(__)m
....と思ったら「俺ならこう書く」、投稿できないorz 
また明日来ます。 


とりあえず今のコードの問題点をば 

-- 

1. pinとfrom, poutとtoは文脈的に同じ意味なので、ぱっと見混同します。 
   こういうの見ると、俺のようなダメグラマーは混乱しますorz
2. 直感に反するところにはコメントがほしいです。
   (iconv関数にchar**を渡すのとか、*pout '\0'の行とか一瞬間違いかと思いました。もしかしたら俺だけかも?) 
3. 文字コード変換の時ってlengthを使うと「バイト数」なのか「文字数」なのか混同するので、 
   bytesを使ったほうがいいと思います。 

以下、あんまり重要じゃないきがするけど気になった場所 

a. 定数は大文字がいいです。 
b. pinのように変数名にpをつけるのはいいと思いますが、 
   その場合呼び出し元もtextじゃなくptextにしてほしいです。 
c. pout, olenで、outとするかoとするか統一してほしいです。 
d. iconvの返り値は「呼出しの間に非可逆な方法で変換された文字数」なので、 
   rlen(returned length?)だと不適だと思います。 
e. エラーはいちおう標準エラー出力使って出力してほしいです。 


細かいところばっかごちゃごちゃとすんません。 
逆に、細かい問題点しか思い浮かばないということは「全然ひどくない」ということなんすよね。 

  • GoodJob
  • 0

ちょっと致命的っぽいバグ?があるので報告します。

どうやら、iconvはolen分だけ(NULL終端の分を余らせないで)
しっかりデータを書き込んでくれるみたいなので、
*pout '\0';
はアクセス違反を起こす可能性があります。


それと、配列の宣言時にサイズをconst定数で指定する方法がVisualC8.0だとダメでした。(拡張子をcppやccにすればOK)
やっぱりC言語の場合素直に#defineを使うほうがよいのではと思いました。

  • GoodJob
  • 0

  • ゲスト
  • 10:ゲスト (通りすがりの者ですが)
  • 2007/09/10 01:43

tarのiconvとかを見てると参考になりますよ。

#include <system.h>
#include <quotearg.h>
#include <localcharset.h>
#include "common.h"
#ifdef HAVE_ICONV_H
include <iconv.h>
#endif

#ifndef ICONV_CONST
define ICONV_CONST
#endif

#ifndef HAVE_ICONV

undef iconv_open
define iconv_open(tocode, fromcode) ((iconv_t) -1)

undef iconv
define iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft) ((size_t) 0)

undef iconv_close
define iconv_close(cd) 0

#endif




static iconv_t conv_desc[2] (iconv_t) -1, (iconv_t) -1 };

static iconv_t
utf8_init (bool to_utf)
{
  if (conv_desc[(int) to_utf] == (iconv_t) -1)
    {
      if (to_utf)
    conv_desc[(int) to_utf] iconv_open ("UTF-8", locale_charset ());
      else
    conv_desc[(int) to_utf] iconv_open (locale_charset (), "UTF-8");
    }
  return conv_desc[(int) to_utf];
}

bool
utf8_convert (bool to_utf, char const *input, char **output)
{
  char ICONV_CONST *ib;
  char *ob;
  size_t inlen;
  size_t outlen;
  size_t rc;
  iconv_t cd utf8_init (to_utf);

  if (cd == 0)
    {
      *output xstrdup (input);
      return true;
    }
  else if (cd == (iconv_t)-1)
    return false;

  inlen strlen (input) 1;
  outlen inlen MB_LEN_MAX 1;
  ob *output xmalloc (outlen);
  ib (char ICONV_CONST *) input;
  rc iconv (cd, &ib, &inlen, &ob, &outlen);
  *ob 0;
  return rc != -1;
}


bool
string_ascii_p (const char *str)
{
  const unsigned char *p (const unsigned char *)str;
  for (; *p; p++)
    if (*p 127)
      return false;
  return true;
}

  • GoodJob
  • 0

strlen使ってるのでUTF-16とかの入力があったとき失敗することがあるみたいです。
http://code.nanigac.com/source/view/126 のコードでは修正しました。

正直iconvのインターフェースはstrncpyやgets並に悪意がこもっていると思います。



  • GoodJob
  • 0

  • l-w-i
  • 13:l-w-i
  • 2008/08/21 02:28

軟弱者の僕はコマンドでやっちゃってます...

(Solarisの場合)
http://l-w-i.net/t/solaris/iconv_001.txt

  • GoodJob
  • 0

  • ゲスト
  • 14:ゲスト (iconv初心者)
  • 2008/08/23 01:02

iconvを使っているんですが、
詳しい方に教えて頂きたいことがあります。

iconv_openの中では何をしているんでしょうか?

っというのも、iconv_openの前にcallocをしているんですが、
iconv_open実行後にそのcallocで確保したメモリの中を
破壊しているようなんです。

言語はc言語です。
OSは若干特殊でHP-UXを使っています。

どなたか、わかる方がいらっしゃいましたら教えてください。

よろしくお願いします。

  • GoodJob
  • 0

  • ゲスト
  • 15:ゲスト
  • 2008/12/16 17:25

http://altalt.dyndns.ws:8080/blog/blosxom.cgi?path=/misc_...

手もとで検証する限りは、正しく動作しました。

  • GoodJob
  • 0

前へ 1 次へ

コメントする

[block]から[/block]までの範囲はブロック表示されます。
部分的に目立たせたい時や、引用などにお使いください。

[code]から[/code]までの範囲は等幅表示されます。
ソースコードや設定ファイルの記述などにお使いください。

ゲスト投稿者:ゲスト:

PDFLib | A library for processing PDF on the fly プレゼン公開・共有サイト handsOut.jp オープンタイプ株式会社 チーム・マイナス6% - みんなで止めよう温暖化

ソースコードのブログパーツ

デフォルトのフォントサイズ
修飾
表示サイズ
px px
プレビュー (表示する)
下のプレビュー領域をクリックすると、ポップアップで全体を見ることができます。
パラメータが不正です

    GoodJobしたユーザ

    ブックマークコメント

    関連するなにがし

    前へ 1 次へ

    タグ

    dyndnsbytearrayinputstreamobjectinputstreambytearrayoutputstreamobjectoutputstreamディープコピーdeepcopyarraylistiteratorチェックボックス複数multibytexencentos文字エンコーディングinit_connectcharacter-set-servercollation-serverdefault-character-setf:label動的メソッド呼び出しヘルパーメソッドwsse2重登録防止prototype.js位置positionpositionedoffsetscrolltoスクロールlink_tocyclecheck_box_tagチュートリアルactive_formerror_messages_forハイライトバリデーションvalidate便利リストデコレーションメールデコメ非対応機種tilestext_field_tag一括複数情報etherealrtphexテキストデータ抽出validwhenリセット一括更新plop置換replacepcoslogmixisregソケットnet::telnetfopenmutexサンプルcalendar[linux][bash][シェルスクリプト][大容量]mobilerorrails2.1clipboardクリップボード横向きピラミッドs2jdbc-genjsonicお絵かきフルパス名抽出サブドメインサブドメイン名s2jdbc自動生成エンティティドコモxhtmlrestdoltengspidering背景変更グラデーションiso一括登録xトークンチェックevalmonitorslavereplication画像処理

    前へ 1 2 3 ... 8 次へ