使用C.UTF-8作为当前语言环境时,fseek / ftell出现意外结果

时间:2014-05-12 15:50:14

标签: c utf-8 glibc fseek ftell

我正在测试fseek和fgetpos的交互(更确切地说,如果我能得到一个多字节内的fpos_t)并且进入一个非常意外的情况。

每当我使用setlocale(LC_CTYPE, "C.UTF-8");fputwc时,fseek似乎不再起作用,将光标移动到文件中的唯一方法是使用fgetwc

代码如下(所有调用成功完成,即setlocale,fseek,fputwc等等。为简洁起见,我删除了返回值的检查)。

这在Ubuntu上发生了glibc 2.16。有没有人有一个很好的解释为什么会这样?这是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

一些注意事项:

  • 如果我关闭文件并在阅读中重新打开它,那么一切都按预期工作(fseek后,ftell_out / fpos_out1和{{由于位置在多字节内,因此1}}失败并显示正确的fgetwc

  • 如果我不使用errno,则输出几乎与预期一致,只是setlocale不再设置fgetwc

0 个答案:

没有答案