2

例如,我想用完整的反斜杠-n(无格式std::string my_str( "foobar\n" );)直接写入。std::ostream&

也许我需要先my_str使用将反斜杠转换为双反斜杠的格式化函数进行转换?有没有一个标准的库函数呢?

或者也许有一个指令我可以传递给std::ostream&

4

4 回答 4

6

对于较大的字符串,最简单的方法是使用原始字符串文字:

std::string my_str(R"(foobar\n)");

如果要在其中使用括号,请使用分隔符:

R"delim(foobar\n)delim"

我不知道有什么可以让您将转义码等保留在字符串中,但没有输出它,但std::transform有一个std::ostream_iterator<std::string>目的地和一个处理您想要的情况的函数应该这样做,就像在这个例子中一样:

std::string filter(char c) {
   if (c == '\n') return "\\n";
   if (c == '\t') return "\\t";
   //etc
   return {1, c};
}

int main() {
   std::string str{"abc\nr\tt"};
   std::cout << "Without transform: " << str << '\n';

   std::cout << "With transform: ";
   std::transform(std::begin(str), std::end(str), std::ostream_iterator<std::string>(std::cout), filter);
}
于 2013-02-13T07:24:42.267 回答
4

既然"foobar\n"是常量字面量,就写成"foobar\\n", 这样"\\"就变成了"\",让n离开。

你所说的“格式化”不是。

流不格式化字符串。"\n"with的替换char(10)是由编译器在从文字生成实际值时进行的。(如果底层平台需要,ostream 最多会转化char(10){ char(10), char(13) },但这是另一回事)。

于 2013-02-13T07:33:23.253 回答
2

“反斜杠+n”没有被流格式化;例如长度std::string("\n")1(而不是 2)。同样'\n'是单个字符。您编写反斜杠 + n 的事实只是表示不可打印(和非 ASCII)字符的快捷方式。

再举一个例子,'\x0a' == '\n'(因为0a是换行符的十六进制代码)。而且std::string("\x0a").size() == 1也是。

如果(在 Linux 1上)您打开 astd::ofstream并写入'\x0a'该流,那么您最终将得到一个包含单个字节的文件;其十六进制值为0a

因此,转换您编写的内容的不是您的流,而是编译器。根据您的用例,您可能想要:

  • 更改代码中写入的字符串:使用"foobar\\n"(注意这将长度增加1)
  • 在流式传输时执行转换以打印不可打印字符的十六进制或转义码

1在 Windows 上,'\n'字符在文本模式下被转换为"\r\n"(回车 + 换行)。

于 2013-02-13T07:53:04.200 回答
2

这与std::ostreamor无关std::string"foobar\n"是一个\n已经意味着行尾的文字。

你有两个选择:

  1. 转义\n符号\

    std::string str("foobar\\n");

  2. 使用现代 C++11 原始字符串文字

    std::string str(R"(foobar\n)");
于 2013-02-13T07:43:28.043 回答