如何写入std :: ostream而不进行格式化?

时间:2013-02-13 07:23:22

标签: c++ c++11 io formatting

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

也许我需要使用格式化函数转换my_str,该函数首先将反斜杠转换为双反斜杠?是否有标准的库函数?

或许我可以将指令传递给std::ostream&

4 个答案:

答案 0 :(得分:6)

对大字符串执行此操作的最简单方法是使用原始字符串文字:

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

如果您想要括号,请使用分隔符:

R"delim(foobar\n)delim"

我不知道任何能让你在字符串中保留转义代码等的东西,但输出它没有,但是std::transform有一个std::ostream_iterator<std::string>目的地和一个处理案例的函数你应该这样做,就像在this example中一样:

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

答案 1 :(得分:4)

由于"foobar\n"是一个常量字面值,只需将其写为"foobar\\n",以便"\\"变为"\",让n平静下来。< / p>

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

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

答案 2 :(得分:2)

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

您有两种选择:

  1. \n转发\符号

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

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

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

答案 3 :(得分:2)

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

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

如果(在Linux 1 上)打开std::ofstream并将'\x0a'写入该流,您将最终得到一个包含 single <的文件/ em> byte;其十六进制值为0a

因此,您的流不是正在改变您所写的内容,而是编译器。根据您的用例,您可能希望:

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

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