读取ANSI编码文本作为宽字符串

C++ - read ANSI encoded text as wide character string

本文关键字:字符串 文本 ANSI 编码 读取      更新时间:2023-10-16

我的目标是读取ANSI编码的文本。但由于某些原因,我使用fgetws()(不是fgets)函数,当然文件是以二进制模式打开的。下面是演示我的问题的简短代码

  bool testfunc(wchar_t path[])
  {
     wchar_t buffer[10];
     if( FILE * fr=_wfopen(path,L"rb") )
     {
        fgetws(buffer,sizeof(buffer),fr);
        fclose(fr);
        return true;
     }
     else return false;
  }

当我调用这个函数并传递ANSI编码的文本文件路径作为参数时,在运行时出现访问冲突错误。当文本大小足够大时,似乎会发生错误。我不知道问题出在哪里。

根据文档,fgetws的第二个参数是数组中的宽字符数,而不是字节数,所以:

fgetws(buffer,sizeof(buffer)/sizeof(*buffer),fr);
一个有用的经典宏是:
#define countof(x) (sizeof(x)/sizeof(*(x)))

或者一个花哨的c++模板:

template <typename T, int N>
int countof(T (&a)[N])
{
    return N;
}

如果文件只包含ASCII字符(请记住ASCII是Unicode的子集,并且wchar_t的大小是特定于实现的,并且可能适合Unicode字符子集的某些固定宽度编码;所以wchar_t不是很便携)你需要将每个单独的ASCII字符转换为其宽字符等效:

{
#define SIZE 80
    char cbuf[SIZE];
    wchar_t wbuf[SIZE];
    char* pc;
    wchar_t* pw;
    memset (cbuf, 0, sizeof(cbuf));
    memset (wbuf, 0, sizeof(wbuf));
    fgets (cbuf, SIZE, fr);
    for ((pc=cbuf), (pw=wbuf); pc<cbuf+SIZE && *pc != 0; pc++, pw++)
      *pw = (wchar_t) *pc;
}

注:仔细阅读fgetws(3)手册页的NOTES。可以理解为吓人