4

我正在尝试将保存在 dics 上的文件内容加载到字符串中。该文件是 .CS 代码,在 VisualStudio 中创建,所以我想它以 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 文件的内容),然后出现奇怪的符号,如 췍췍췍췍췍췍췍췍췍췍췍췍췍췍췍췍췍췍췍췍췍췍췍。所以我认为我以错误的方式阅读了内容。但是如何正确地做到这一点?非常感谢,我期待听到!

4

3 回答 3

3

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); 
于 2010-05-17T21:11:10.393 回答
1

该字符串是否包含 cs 文件的所有内容以及其他有趣的字符?可能它只是没有正确地以空值终止,因为fread不会自动这样做。您需要将字符串内容后面的字符设置为零:

lpContent[lSize] = 0;
于 2010-05-17T21:10:31.880 回答
0

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

s2ws 函数将字符串转换为 wstring

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));
于 2019-11-27T12:23:00.430 回答