【问题标题】:endl doesn't work with wstring (unicode)endl 不适用于 wstring (unicode)
【发布时间】:2012-05-08 23:09:44
【问题描述】:

代码如下:

  std::ofstream f("file1.txt");
  f<<"123"<<std::endl<<"456";           //(*1)

  /*std::stringstream ordinary_strstream; This works too
  ordinary_strstream<<"123"<<'\n'<<"456";
  f<<ordinary_strstream.str();*/

  std::wstringstream s;
  s<<L"123"<<std::endl<<L"456";         //(*2)
  s<<L"123"<<L"\n"<<L"456";             //(*3) 
  s<<"123"<<WCHAR(13)<<WCHAR(10)<<"456";//(*4)

  HANDLE h =CreateFileW(L"file2.txt", GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

  ULONG l;
  WriteFile(h, s.str().c_str(), s.str().length() * 2, &l, NULL);

在 (*1) 情况下,有一个换行符,在 (*2) 和 (*3) 中,我在 file2.txt 中看不到换行符。在 (*3) 中有一个换行符。我使用notepad.exe 进行浏览。十六进制编辑器不显示 0x0D 字节,仅显示 0x0A

我应该如何正确地将换行符放入 unicode 文本文件中?谢谢。

【问题讨论】:

  • 2 应该是 sizeof(wchar_t),不是吗?
  • 2 只是为了简化,在原始代码中当然有std::wstring::value_type。
  • 小心你的术语。 Unicode 是代码点的规范。从技术上讲,您存储在文件中的是 Unicode 编码。如果您使用的是 Windows 和 wchar_t,这可能是 UTF-16

标签: c++ windows unicode newline wstring


【解决方案1】:

字符串流不进行行尾转换。 std::endl\n 完全相同(char 或 wchar,取决于上下文)。

CreateFile 不做行尾转换;它是严格的二进制。

因此,当您使用字符串流创建字符串并将其写入带有CreateFile 的文件时,endl 将只是换行符 (0x0A)。

记事本不能很好地处理行尾只是换行符而不是 CR+LF 的文件。

【讨论】:

  • 但是普通的stringstream可以做到。我已经更新了代码,如果你想试试。
  • fstream 进行转换,而不是字符串流。
【解决方案2】:

这是预期的:std::endlL'\n' 写入宽字符流(并刷新它,但在这里不相关),绝不是 L"\r\n"。在编写文字 L"\n" 时更加明显。 WriteFile 不执行任何换行符替换,wstringstream 也不执行(请注意,文件流在文本模式下打开时执行换行符替换,这就是为什么您在 @ 中得到正确的换行符987654327@)。因此,文件中不会有回车符。如果你想要它们,请明确地写出来。

【讨论】:

  • 你的意思是它只取“\n”的第一部分(0x0A),加零以形成宽字符,将字符放入wstringstream并抛出第二部分(0x0D)离开?我理解对了吗?
  • @fogbit:不,没有东西被扔掉。您已经编写了代码,以便它写入L'\n',因此wstringstreamL'\n' 写入其内部字符串。不多也不少。它不知道你的意思是L"\r\n",所以如果你想告诉它。
  • @fogbit:“普通字符串”是什么意思?
  • 我的意思是std::stringstd::stringstream
  • @fogbit:如果您指的是刚刚添加的注释掉的部分,那是因为您正在写入以文本模式打开的文件流。转换换行符的是文件流,而不是字符串流。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-12
  • 2013-03-25
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 2020-10-18
相关资源
最近更新 更多