如何修复MFC CStdioFile和CString乱码,同时读取和处理文件中的数据?

How to Fix MFC CStdioFile and CString Garbled Characters while Reading and Dealing with Data in Files?

提问人:Edward Tsui 提问时间:11/1/2023 最后编辑:Remy LebeauEdward Tsui 更新时间:11/2/2023 访问量:92

问:

Visual Studio 2019 社区版和 MFC

我的代码:

void CTMCVDlg::FileIO()
{
//  Getting source file path to read and destination file path to write
    CString    destpath, sourcepath, destname;
    GetDlgItemText(IDC_EDIT1, sourcepath);
    GetDlgItemText(IDC_EDIT1, destpath);
    GetDlgItemText(IDC_EDIT2, destname);
    destpath = GetFilePathExceptFileName(destpath);
    CStdioFile outF(destpath + destname + _T(".osu"), CFile::modeWrite | CFile::modeCreate);
    CStdioFile inF(sourcepath, CFile::modeRead | CFile::typeBinary);
//    Operation Log
    AppendText3(_T("Created and opened file \"") + filename + _T(".osu\""));
    AppendText3(_T("Converting..."));
/*
*    I want to read the source file line by line and when I meet a line with 'TimingPoints' the loop stops.
*    szline: read file line by line
*    temp: special string for exception of regular options
*    aa: not used
*/
    CStringW szline = _T("");
    CString temp = _T("");
    CStringA aa = "";
    while (inF.ReadString(szline))
    {
        AppendText3(szline);    // Just debug for what it read
        if (szline.Find(_T("Mode:")) != -1)    // If it meets a line including 'Mode:' then write 'Mode: 3'
        {
            temp = _T("Mode: 3");
            outF.Write(temp, temp.GetLength() << 1);
            outF.Write("\r\n", 2);
        }
        else // else write what it has read.
        {
            outF.Write(szline, szline.GetLength() << 1);
            outF.Write("\r\n", 2);
        }
        if (szline.Find(_T("TimingPoints")) != -1)    // if it meets 'TimingPoints' then exit the loop.
        {
            break;
        }
    }
}

输入文件:
image

输出文件:
image

调试:
image

文本文件编码:UTF-8

我想知道,为什么在读取 CString 对象时这一切都变成了乱码?

另外,为什么输出文件有很多多余的空换行符?

此外,我不能让循环结束,因为它找不到“TimingPoints”和“Mode:”关键字。我尝试使用宏将宽字符转换为 UTF-8 字符,但输出文件充满了乱码。CW2A

我想逐行读取输入文件并搜索关键字以进行不同的操作。

C++ 文件-IO MFC 可视化工作室-2019

评论

5赞 IInspectable 11/1/2023
您正在阅读被重新解释为 UTF-16 的 UTF-8 文本。这发生在这里:.如果文件使用窄字符编码,则需要读入窄字符串。代码中还有很多其他错误,您应该仔细阅读以下内容: 绝对最低限度 每个软件开发人员绝对必须了解 Unicode 和字符集(没有借口!inF.ReadString(szline)
1赞 Jabberwocky 11/1/2023
顺便说一句:不要发布文字图片。将文本作为格式正确的文本发布。
0赞 Edward Tsui 11/2/2023
我读了,但仍然不知道如何修复代码并实现功能......对不起,我是一个编程菜鸟

答:

0赞 Constantine Georgiou 11/2/2023 #1

由于缺乏适当的功能,您无法真正逐行读取文件:

  • CStdioFile::ReadString()两者都需要文件中的 Unicode 内容,并返回一个 Unicode 字符串(假设您使用 Unicode 选项进行编译)。不幸的是,没有读取字符串的重载版本。ReadString()CStringA
  • CFile类没有可以逐行读取文件的函数,该类基本上用于二进制文件 I/O。

我可以想到两种可能的解决方案:

  • 每次使用该类读取文件的一部分。您将读取一个缓冲区,并且必须将其转换为宽字符串,并实现自己的缓冲区管理和行分隔。CFile
  • 不要使用 /,而是使用 C++ 类,甚至是 C 函数。CFileCStdioFile

评论

0赞 Edward Tsui 11/2/2023
好的,谢谢,我将尝试另一种方式的std::string;w;