Reputation: 13
I have written a c++ code for changing file formats. Part of the functionality is to add a configured line end character. For one of file conversions, the line end character required is "\r\n" i.e. CR+NL .
My code basically reads the configured value from DB and appends it to the end of each record. Something on the lines of
//read DB and store line end char in a string lets say lineEnd.
//code snippet for file writting
string record = "this is a record";
ofstream outFileStream;
string outputFileName = "myfile.txt";
outFileStream.open (outputFileName.c_str());
outFileStream<<record;
outFileStream<<lineEnd; // here line end contains "\r\n"
But this prints record followed by \r\n as it is, no translation to CR+NL takes place.
this is a record\r\n
While the following works (prints CR+LF in output file)
outFileStream<<record;
outFileStream<<"\r\n";
this is a record
But I can not hard code it. I am facing similar issues with "\n" also.
Any suggestions on how to do it.
Upvotes: 1
Views: 1057
Reputation: 171197
The translation of \r
into the ASCII character CR and of \n
into the ASCII character LF is done by the compiler when parsing your source code, and in literals only. That is, the string literal "A\n"
will be a 3-character array with values 65 10 0
.
The output streams do not interpret escape sequences in any way. If you ask an output stream to write the characters \
and r
after each other, it will do so (write characters with ASCII value 92 and 114). If you ask it to write the character CR (ASCII code 13), it will do so.
The reason std::cout << "\r";
writes the CR character is that the string literal already contains the character 13. So if your database includes the string \r\n
(4 characters: \
, \r
, \
, n
, ASCII 92 114 92 110
), that is also the string you will get on output. If it contained the string with ASCII 13 10
, that's what you'd get.
Of course, if it's impractical for you to store 13 10
in the database, nothing prevents you from storing 92 114 92 110
(the string "\r\n") in there, and translating it at runtime. Something like this:
void translate(std::string &str, const std::string &from, const std:string &to)
{
std::size_t at = 0;
for (;;) {
at = str.find(from, at);
if (at == str.npos)
break;
str.replace(at, from.size(), to);
}
}
std::string lineEnd = getFromDatabase();
translate(lineEnd, "\\r", "\r");
translate(lineEnd, "\\n", "\n");
Upvotes: 2