views:

446

answers:

3

I am writing code that runs in Windows and outputs a text file that later becomes the input to a program in Linux. This program behaves incorrectly when given files that have newlines that are CR+LF rather than just LF.

I know that I can use tools like dos2unix, but I'd like to skip the extra step. Is it possible to get a C++ program in Windows to use the Linux newline instead of the Windows one?

A: 

Are you using printf to write to the file? Have you explored the various combinations of

\n - Newline

\r - Carriage Return

\f - Form Feed

\v - Newline (only some platforms, different from \n)

If those don't work, look into \XXX (where XXX is 3 octal digits, specifying exactly the character code you want)

If you're using cout, try using:

cout << "My Text" << (byte)0x0A;
abelenky
I'm using 'cout << etc << endl;' for the most part. Just doing \n isn't going to work because that just prints the system default.
thornate
`endl` is defined to write `\n` so this won't make any difference. Unfortunately, (byte)0x0A won't work either as the newline translation happens after the characters are sent to the stream. char('\n') and (char)0x0A have the same value on windows.
Charles Bailey
This will only work if you write into a stream that's been opened for binary reading/writing. Otherwise `'\n'` will always be translated from/to a platform-specific sequence.
sbi
(byte)0x0A has no advantage over '\n' (or '\x0a' for that matter); it is the same thing. If line-end translation is set for the stream, it will still be transformed. Moreover byte is a C# type, not C++.
Clifford
@abelenky: When a '\n' goes to a file it text mode it gets translated to a platform specific end of line sequence. When data is read from a file in text mode the end of line sequence is translated into the '\n' character. The problem is that the end of line sequence is different on different platforms.
Martin York
Thats what I get for posting too late at night.... mixing languages, and forgetting translation rules. My apologies. :)
abelenky
+11  A: 

Yes, you have to open the file in "binary" mode to stop the newline translation.

How you do it depends on how you are opening the file.

Using fopen:

FILE* outfile = fopen( "filename", "wb" );

Using ofstream:

std::ofstream outfile( "filename", std::ios_base::binary | std::ios_base::out );
Charles Bailey
Agreed. Open the stream as binary, and no translation takes place. the output of either '\n' or std::endl to such a stream results in a line-feed only.
Clifford
A: 

OK, so this is probably not what you want to hear, but here's my $0.02 based on my experience with this:

If you need to pass data between different platforms, in the long run you're probably better off using a format that doesn't care what line breaks look like. If it's text files, users will sometimes mess with them. If by messing the line endings up doing so they cause your application to fail, this is going to be a support intensive application.

Been there, done that, switched to XML. Made the support guys a lot happier.

sbi