The Man Who Fell From The Wrong Side Of The Sky:2007年9月7日分

[最新版] [一覧] [前月] [今月] [翌月]

2007/9/7(Fri)

[C言語] iconv(3)によるコード変換

http://code.nanigac.com/source/view/20 ネタ。

戻り値(size_t)-1の場合、errnoがEINVALあるいはE2BIGの場合にはリスタート可能なんだけど
そこんとこの処理を端折って一律エラー終了してるからあんまりいい例じゃない罠。

それとiconvの場合、変換前/後のバイト列を固定長で確保するのは正直お薦めしない。
↓ readerから読込んだバイト列をiconv(3)で変換してwriterに書き込む「悪い」サンプル。

	FILE *reader, *writer;
	const char *from, *to;
	iconv_t cd;
	char inbuf[BUFSIZ], outbuf[BUFSIZ], *in, *out;
	size_t inbytes, outbytes, irreversible, ret, nconv;

	irreversible = (size_t)0;
	cd = iconv_open(to, from);
	if (cd == (iconv_t)-1)
		errx(1, "can't iconv");
	while ((inbytes = fread(inbuf, 1, sizeof(inbuf), reader)) > 0) {
		in = &inbuf[0];
		while (inbytes > 0) {
			out = &outbuf[0];
			outbytes = sizeof(outbuf);
			ret = iconv(cd, &in, &inbytes, &out, &outbytes);
			nconv = sizeof(outbuf) - outbytes;
			if (ret == (size_t)-1) {
				switch (errno) {
				case EINVAL:
					… (A)
					break;
				case E2BIG:
					… (B)
					break;
				default:
					errx(1, "can't iconv");
				}
			} else {
				irreversible += ret;
			}
			if (nconv > 0)
				fwrite(outbuf, 1, nconv, writer);
		}
	}
	…

inbuf/outbuf を固定長で確保してるんだけど、これだと (A) (B) の2個所で困ることになる。

つーわけでちゃんと残らず余さず文字コード変換したいなら、動的確保すべし。
この コードを参考にしてみてください。

(追記)
コメントへの返答は 9/8のメモに書いたのでそっちもどうぞ。


*1:厳密には stateful encoding で冗長な escape sequence が続く場合、MB_CUR_MAX は無限大になるんだけどね。
*2:fromのワイド文字数 : toのワイド文字数ね、バイト数の比じゃないです。
*3:んでも mbstate_t と違って iconv_t はコンストラクタ/デストラクタあるんだし動的確保しても良かったと思うんだけどね。

Sony α-700

α-10という噂だったけど、伝統の7ナンバー復活、そつなくまとまってていい感じ。

まあ俺は銀塩であと10年は戦う予定(フィルムがあれば、ね)なので、デジには興味ないんだけど。
α-100になかった シンクロターミナルがついたので
紛失しやすいこれのキャップがまた入手可能になるのはいいことだ。

しかし肝心のレンズの方はDT(APS-C専用設計)3本しかもOEMしか発表ないんか。
マスター…バーボン(以下略
噂の 24mm/F1.4 と 24-70mm/F2.8G には期待してたんだけどなぁ。


[ホームへ] [ページトップへ]