在C++中错误地读取UNICODE文件(使用fread)

4

我正在尝试将磁盘上保存的文件内容加载到字符串中。这个文件是VisualStudio创建的.CS代码文件,我认为它以UTF-8编码保存。我正在进行以下操作:

FILE *fConnect = _wfopen(connectFilePath, _T("r,ccs=UTF-8"));
    if (!fConnect)
        return;
    fseek(fConnect, 0, SEEK_END);
    lSize = ftell(fConnect);
    rewind(fConnect);

    LPTSTR lpContent = (LPTSTR)malloc(sizeof(TCHAR) * lSize + 1);
    fread(lpContent, sizeof(TCHAR), lSize, fConnect);

但结果很奇怪-第一部分(字符串的一半是.CS文件的内容),然后是奇怪的符号,如췍췍췍췍췍췍췍췍췍췍췍췍췍췍췍췍췍췍췍췍췍췍。所以我认为我以错误的方式读取了内容。但是应该如何正确地做到这一点呢?非常感谢您,期待听到您的回音!
3个回答

4

ftell()、fseek()和fread()都是按字节操作,而不是按字符操作。在Unicode环境中,TCHAR至少为2个字节,因此您分配和读取的内存是应有的两倍。

我从未见过fopen()或_wfopen()支持“ccs”属性。您应该使用“rb”作为读取模式,将原始字节读入内存,然后在所有内容都可用后进行解码,例如:

FILE *fConnect = _wfopen(connectFilePath, _T("rb")); 
if (!fConnect) 
  return; 
fseek(fConnect, 0, SEEK_END); 
lSize = ftell(fConnect); 
rewind(fConnect); 

LPBYTE lpContent = (LPBYTE) malloc(lSize); 
fread(lpContent, 1, lSize, fConnect);
fclose(lpContent);

.. decode lpContent as needed ...
free(lpContent); 

我不明白如何解码它。我只需要将文件内容作为Unicode字符串获取(实际上我想将其复制到缓冲区中)。取得的lpContent长度仅为先前lpContent的一半,这正常吗? - mimic

1
字符串是否包含了cs文件的所有内容,然后还有一些“额外”的有趣字符?可能它只是没有正确地以 null 结尾,因为 fread 不会自动执行这个操作。你需要将字符串内容后面的字符设置为零:
lpContent[lSize] = 0;

0

..根据需要解码lpContent...

s2ws函数将字符串转换为宽字符串

std::wstring s2ws(const std::string& str)
{
    int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
    std::wstring wstrTo(size_needed, 0);
    MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
    return wstrTo;
}

在缓冲区的末尾添加空终止符:
lpContent[lSize-1] = 0;

从缓冲区内容初始化wstring

std::wstring replyStr = (s2ws((char*)lpContent));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接