简体   繁体   中英

How to write to std::ostream without formatting?

For example, I want to write std::string my_str( "foobar\\n" ); literally into std::ostream& with the backslash-n intact ( no formatting ).

Perhaps I need to convert my_str with a formatting function that converts backslash to double-backslash first? Is there a standard library function for that?

Or maybe there is a directive I can pass to std::ostream& ?

The easiest way to do this for larger strings is with raw string literals:

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

If you want parentheses in it, use a delimiter:

R"delim(foobar\n)delim"

I don't know of anything that will let you keep the escape codes etc. in the string, but output it without, but std::transform with an std::ostream_iterator<std::string> destination and a function that handles the cases you want should do it, as it does in 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);
}

Since "foobar\\n" is a constant literal, just write it as "foobar\\\\n" , so that "\\\\" becomes "\\" , letting n to leave in peace.

What you call "formatting" is not.

The stream does not format the string. The substitution of "\\n" with char(10) is made by the compiler when producing the actual value form the literal. (ostream will at most translate char(10) into { char(10), char(13) } if the underlying platform requires it, but that's another story).

This is not related to std::ostream or std::string . "foobar\\n" is a literal where \\n already means end of line.

You have two options:

  1. Escape \\n symbol by \\

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

  2. Use modern C++11 raw string literal

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

The "backslash + n" is not formatted by the stream; for example the length of std::string("\\n") is 1 (and not 2). Likewise '\\n' is a single character . The fact that you write backslash + n is just a shortcut to represent non-printable (and non-ASCII) characters.

As another example, '\\x0a' == '\\n' (because 0a is the hexadecimal code for the line-feed character). And std::string("\\x0a").size() == 1 too.

If (on Linux 1 ) you open a std::ofstream and write '\\x0a' to that stream, you will thus end up with a file containing a single byte; whose hexadecimal value is 0a .

As such, it is not your stream that is transforming what you wrote, it is the compiler. Depending on your usecase, you may either want to:

  • change the string as written in the code: using "foobar\\\\n" (note this increase the length by 1)
  • perform a transformation while streaming to print the hexadecimal or escape code of non-printable characters

1 on Windows, the '\\n' character is translated to "\\r\\n" (carriage-return + line-feed) in text mode.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM