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

问题描述 投票:0回答:1

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;
        }
    }
}

输入文件:

输出文件:

调试:

文本文件编码:UTF-8

我就想知道,为什么读入CString对象的时候全都变成乱码了?

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

另外,我不能让循环结束,因为它找不到“TimingPoints”和“Mode:”关键字。我尝试使用

CW2A
宏将宽字符转换为UTF-8字符,但是输出文件变成了乱码。

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

c++ file-io mfc visual-studio-2019
1个回答
0
投票

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

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

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

  • 使用
    CFile
    类每次读取文件的一部分。您将读取一个缓冲区,并且必须将其转换为宽字符串并实现您自己的缓冲区管理和行分隔。
  • 不要使用
    CFile
    /
    CStdioFile
    ,而是使用 C++ 类,甚至 C 函数。
© www.soinside.com 2019 - 2024. All rights reserved.