2

fseek と fgetpos の相互作用をテストしていたところ (より正確には、マルチバイト内にある fpos_t を取得できるかどうか)、かなり予期しない状況に陥りました。

setlocale(LC_CTYPE, "C.UTF-8");andを使用するたびにfputwcfseekもう機能しないようで、ファイル内でカーソルを移動する唯一の方法は を使用することfgetwcです。

コードは次のとおりです (すべての呼び出しは正常に完了します。つまり、setlocale、fseek、fputwc などです。簡潔にするために、戻り値のチェックを取り除きました)。

これは、glibc 2.16 を使用する Ubuntu で発生します。なぜこれが起こるのか、誰かが良い説明を持っていますか? これは glibc のバグですか?

setlocale(LC_CTYPE, "C.UTF-8");
uselocale(LC_GLOBAL_LOCALE);

FILE* fp = fopen("/tmp/wc.test", "w+");

wchar_t wc = 0x00a2;
fputwc(wc, fp);
fflush(fp);

rewind(fp);

long ftell_out;
fpos_t fpos_out;

fseek(fp, 1, SEEK_SET);   // looks like it doesn't have any effect
ftell_out = ftell(fp);    // ftell_out is 0
fgetpos(fp, &fpos_out);   // the (inner) offset of fpos_out is 0 as well

fgetwc(fp);               // it reads wc(0x00a2) here as if we are at
ftell_out = ftell(fp);    // this is 2
fgetpos(fp, &fpos_out);   // this is 2

いくつかのメモ:

  • ファイルを閉じて read more で再度開くと、すべてが期待どおりに機能します (位置がマルチバイト内にあるためfseekftell_out/fpos_outが適切1fgetwc失敗した後)errno

  • 私が使用しない場合setlocale、出力はほとんど期待どおりですfgetwcが、もう設定されていませerrnoん。

4

0 に答える 0