【问题标题】:C++ Strange characters appear when writing to text file写入文本文件时出现 C++ 奇怪的字符
【发布时间】:2015-09-07 04:14:03
【问题描述】:

我有一个程序,每当在相机上拍摄照片时,它就会写出帧号和当前系统时间:

SYSTEMTIME st;
GetSystemTime(&st);
lStr.Format( _T("%d   %d.%d.%d.%d\r\n"),GetFrames() ,st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);

std::wfstream myfile;  
myfile.open("test.txt", std::ios::out | std::ios::in | std::ios::app );
    if (myfile.is_open())
            {
            myfile.write((LPCTSTR)lStr, lStr.GetLength()*sizeof(TCHAR));
            myfile.close();
            }
        else {lStr.Format( _T("open file failed: %d"), WSAGetLastError());
        }

程序输出的文本文件似乎正确地写入了数据,但我得到的空格和字符不应该出现在每行的开头。该网站似乎没有正确格式化空格,所以我会发布一张图片,这就是文本文件的样子。该文件有时还会显示除零之外的项目符号。

如您所见,第一行很好,但我写入文本文件的时间越长,它似乎变得越糟。该程序每秒写入文件大约 10 次。我是 C++ 新手,我不确定是什么原因造成的。我试图寻找与此类似的其他问题,但他们似乎没有我正在寻找的解决方案。任何帮助将不胜感激。

【问题讨论】:

  • GetFrames 返回什么?诠释?
  • 我怀疑它是行尾的\r\n。当您以文本格式(IE,而不是二进制)打开它时,\n 将在 Windows 上自动翻译为 '\r\n'。
  • 这是一个双字,我应该使用双字吗?
  • DWORD 是 unsigned long,这很好。
  • wfstream::write 的第二个参数是以字符为单位的缓冲区大小,而不是您所假设的以字节为单位的大小。您写入字符串的n 字符,然后写入恰好在内存中跟随的随机垃圾的n 字符。删除* sizeof(TCHAR) 部分。

标签: c++ visual-studio-2010 text fstream


【解决方案1】:

解决方案有两部分:

lStr.Format( _T("%d   %d.%d.%d.%d\r\n"),GetFrames() ,st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);

应该是

lStr.Format( _T("%lu   %d.%d.%d.%d\n"),GetFrames() ,st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);

由于GetFrames() 返回DWORD,即unsigned long,并且您正在将文件写入文本,因此\n 将在需要时转换为\r\n,具体取决于操作系统。

另一部分是wfstream::write的第二个参数是字符数而不是字节数所以

myfile.write((LPCTSTR)lStr, lStr.GetLength()*sizeof(TCHAR));

应该是

myfile.write((LPCTSTR)lStr, lStr.GetLength());

【讨论】:

    【解决方案2】:

    当您使用std::wfstream::write (basic_ostream) 时,它会占用您的字符串的大小。你再用* sizeof(TCHAR) 乘以那个大小。删除这个额外的乘法应该可以解决您的问题。


    虽然如果您有其他问题(例如第三方库返回的空格过多),您可以随时修剪字符串。

    一个基本的例子:

    template<class TString>
    static inline TString &trim_left(TString &s)
    {
        s.erase(std::begin(s), std::find_if(std::begin(s), std::end(s), std::not1(std::ptr_fun<int, int>(std::isspace))));
        return s;
    }
    
    template<class TString>
    static inline TString &trim_right(TString &s)
    {
        s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), std::end(s));
        return s;
    }
    
    template<class TString>
    static inline TString &trim(TString &s)
    {
        return trim_left(trim_right(s));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-09
      相关资源
      最近更新 更多