"\n" vs std:endl

X

Xian

Is there a right and proper (tm) way to end a line? Thinking about
portability and the mess that the 'wrong' line endings can cause.

E.g.
std::cout << "Hello World!\n";
or
std::cout << "Hello World!" << std::cout;
 
A

AnonMail2005

Is there a right and proper (tm) way to end a line? Thinking about
portability and the mess that the 'wrong' line endings can cause.

E.g.
std::cout << "Hello World!\n";
or
std::cout << "Hello World!" << std::cout;
std::endl places a newline plus flushes the buffer so it's
different than just a newline.

You can avoid this by making an output class handle
newlines and buffer flushing so you can just output
your message content.

Plus by putting this in a (configurable) class, these
two decisions aren't littered throughout your code.
 
D

Daniel T.

Xian said:
Is there a right and proper (tm) way to end a line? Thinking about
portability and the mess that the 'wrong' line endings can cause.

E.g.
std::cout << "Hello World!\n";
or
std::cout << "Hello World!" << std::endl; // corrected

To use std::endl after every line is a premature pessimization AFAIC.
Using '\n' will allow the system to flush when its most efficient rather
than forcing it to flush the buffer unnecessarily.
 
S

Salt_Peter

Xian said:
Is there a right and proper (tm) way to end a line? Thinking about
portability and the mess that the 'wrong' line endings can cause.

E.g.
std::cout << "Hello World!\n";
or
std::cout << "Hello World!" << std::cout;

You might consider only using std::endl when you need the output
flushed, since thats what it does after a newline is injected. If you
prefer not having to write "\n" you could also define some char
constant or std::string constant like:

#include <iostream>
#include <ostream>

const char NL('\n');

int main()
{
std::cout << "hello!" << NL;
}
 
J

Jacek Dziedzic

Xian said:
Is there a right and proper (tm) way to end a line? Thinking about
portability and the mess that the 'wrong' line endings can cause.

E.g.
std::cout << "Hello World!\n";
or
std::cout << "Hello World!" << std::cout;
**********

As other have already pointed out, std::endl (* not std::cout)
flushes the output buffer so performance will suffer if you
output a lot of lines. On the other hand, if you want flushing
(eg. in debug statements) flushing may be desirable.

But I believe you are really worried about newline translation,
ie. '\n' vs "\r\n". Don't worry -- this translation should happen
automatically, behind the scenes. For example in a Windows-based
system, even though you output '\n', "\r\n" will be written.
Conversely, during reading, even though the file in fact contains
"\r\n", your program will only see a single 'newline'.

HTH,
- J.
 
X

Xian

Jacek said:
As other have already pointed out, std::endl (* not std::cout)
Oops yeah, glad you people can read what I mean to write not what I
actually do. hehe
flushes the output buffer so performance will suffer if you
output a lot of lines. On the other hand, if you want flushing
(eg. in debug statements) flushing may be desirable.
I didn't know it flushed the stream, now I see the reason for having both
versions.
But I believe you are really worried about newline translation,
ie. '\n' vs "\r\n". Don't worry -- this translation should happen
automatically, behind the scenes. For example in a Windows-based
system, even though you output '\n', "\r\n" will be written.
Conversely, during reading, even though the file in fact contains
"\r\n", your program will only see a single 'newline'.
Cheers. That is what I was really asking. I see how the writing of a '\n'
works but the reading.
Is it that the \r on a windows system is discarded when it is read in in a
\r\n pair? And only for files open in ASCII mode?
Does this also mean that I cant tell how many bytes have been written to
the file just by counting how many bytes I send to the stream?

I feel I have been unknowingly overlooking a fair bit of stuff. Anything
you would recommend reading?
 
B

BobR

/* """
Xian wrote in message ...
Jacek said:
But I believe you are really worried about newline translation,
ie. '\n' vs "\r\n". Don't worry -- this translation should happen
automatically, behind the scenes. For example in a Windows-based
system, even though you output '\n', "\r\n" will be written.
Conversely, during reading, even though the file in fact contains
"\r\n", your program will only see a single 'newline'.

Cheers. That is what I was really asking. I see how the writing of a '\n'
works but the reading.
Is it that the \r on a windows system is discarded when it is read in in a
\r\n pair? And only for files open in ASCII mode?
Does this also mean that I cant tell how many bytes have been written to
the file just by counting how many bytes I send to the stream?

I feel I have been unknowingly overlooking a fair bit of stuff. Anything
you would recommend reading?
/One (slightly) enlightened Xian
""" */

Try this:

// ------------
#include <iostream> // #include <ostream>
#include <string>
#include <vector>

int main(){ using std::cout; // for NG post
// put the name of a *short* file in the next string.
std::string FileName("ZZtest.txt");
// 1
std::ifstream sfin(FileName.c_str(),
std::ios_base::in|std::ios_base::binary );
// 2
// std::ifstream sfin( FileName.c_str() ); // try this second

if( not sfin.is_open() ){
cout<<"\n ifstream sfin FAILED"<<std::endl;
return 1; // EXIT_FAILURE
}
std::vector<unsigned char> Image;
char In(0);
while( sfin.get( In ) ){
Image.push_back( static_cast<unsigned char>( In ) );
}
sfin.close();
cout<<"\n Image.size() = "<<Image.size()<<" bytes."<<std::endl;
for( size_t i(0); i < Image.size(); ++i ){
int out( static_cast<int>( Image.at( i ) ) );
cout<<std::setw(3)<<out<<" ";
if((i>0)&&(i%10) == 0){ cout<<std::endl;}
}
cout<<std::endl;
return 0;
} // main()
// ------------

[ Are you on a windows machine? (You may get different output.) ]
In the output, look for "13 10". That's the cr-lf pair. (ANSI ASCII)
Now try (un-comment 2, comment 1) the second file-open version (non-binary).
Still see the '13'?

// ------------
int out( static_cast<int>('\n') );
cout<<"'\\n'="<<std::setw(3)<<out<<std::endl;
out = static_cast<int>('\r');
cout<<"'\\r'="<<std::setw(3)<<out<<std::endl;
/* - output - (MinGW GCC)
'\n'= 10
'\r'= 13
*/
// ------------
you would recommend reading?

Sites: Dinkumware, Boost.

Get "Thinking in C++", 2nd ed. Volume 1&2 by Bruce Eckel
(available for free here. You can buy it in hardcopy too.):
http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html

*THE* FAQ has lots of really good stuff:
The comp.lang.c++ FAQ is available at http://www.parashift.com/c++-faq-lite/
 
R

Rolf Magnus

Xian said:
Cheers. That is what I was really asking. I see how the writing of a '\n'
works but the reading.
Is it that the \r on a windows system is discarded when it is read in in a
\r\n pair?
Yes.

And only for files open in ASCII mode?

You mean text mode. Files are by default opened in text mode, so the
translation happens automatically, unless you explicitly ask for it not to
happen (by opening in binary mode).
Does this also mean that I cant tell how many bytes have been written to
the file just by counting how many bytes I send to the stream?

Yes.
 
X

Xian

BobR said:
Xian wrote in message ...

Is it that the \r on a windows system is discarded when it is read in
in
a \r\n pair? And only for files open in ASCII mode?
Try this:

// ------------
#include <iostream> // #include <ostream>
#include <string>
#include <vector>

int main(){ using std::cout; // for NG post
// put the name of a *short* file in the next string.
std::string FileName("ZZtest.txt");
// 1
std::ifstream sfin(FileName.c_str(),
std::ios_base::in|std::ios_base::binary );
// 2
// std::ifstream sfin( FileName.c_str() ); // try this second

if( not sfin.is_open() ){
cout<<"\n ifstream sfin FAILED"<<std::endl;
return 1; // EXIT_FAILURE
}
std::vector<unsigned char> Image;
char In(0);
while( sfin.get( In ) ){
Image.push_back( static_cast<unsigned char>( In ) );
}
sfin.close();
cout<<"\n Image.size() = "<<Image.size()<<" bytes."<<std::endl;
for( size_t i(0); i < Image.size(); ++i ){
int out( static_cast<int>( Image.at( i ) ) );
cout<<std::setw(3)<<out<<" ";
if((i>0)&&(i%10) == 0){ cout<<std::endl;}
}
cout<<std::endl;
return 0;
} // main()
// ------------

[ Are you on a windows machine? (You may get different output.) ]
In the output, look for "13 10". That's the cr-lf pair. (ANSI ASCII)
Now try (un-comment 2, comment 1) the second file-open version
(non-binary). Still see the '13'?

// ------------
int out( static_cast<int>('\n') );
cout<<"'\\n'="<<std::setw(3)<<out<<std::endl;
out = static_cast<int>('\r');
cout<<"'\\r'="<<std::setw(3)<<out<<std::endl;
/* - output - (MinGW GCC)
'\n'= 10
'\r'= 13
*/
// ------------
you would recommend reading?

Sites: Dinkumware, Boost.

Get "Thinking in C++", 2nd ed. Volume 1&2 by Bruce Eckel
(available for free here. You can buy it in hardcopy too.):
http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html

*THE* FAQ has lots of really good stuff:
The comp.lang.c++ FAQ is available at
http://www.parashift.com/c++-faq-lite/

Cheers. I've played with that program on different systems. And under
stand now thanks :)
Just for the record, here are the results:
Freebsd 6.1-RELEASE-p11 - g++ (GCC) 3.4.4 [FreeBSD] 20050518
TEXT MODE
Image.size() = 21 bytes.
117 'u' 110 'n' 105 'i' 120 'x' 10 109 'm' 97 'a' 99 'c' 13
119 'w' 105 'i' 110 'n' 13 10 119 'w' 101 'e' 105 'i' 114 'r'
100 'd' 10 13
BINARY MODE
Image.size() = 21 bytes.
117 'u' 110 'n' 105 'i' 120 'x' 10 109 'm' 97 'a' 99 'c' 13
119 'w' 105 'i' 110 'n' 13 10 119 'w' 101 'e' 105 'i' 114 'r'
100 'd' 10 13

WinXP - g++ (GCC) 3.3.3 (cygwin special)
TEXT MODE
Image.size() = 21 bytes.
117 'u' 110 'n' 105 'i' 120 'x' 10 109 'm' 97 'a' 99 'c' 13
119 'w' 105 'i' 110 'n' 13 10 119 'w' 101 'e' 105 'i' 114 'r'
100 'd' 10 13
BINARY MODE
Image.size() = 21 bytes.
117 'u' 110 'n' 105 'i' 120 'x' 10 109 'm' 97 'a' 99 'c' 13
119 'w' 105 'i' 110 'n' 13 10 119 'w' 101 'e' 105 'i' 114 'r'
100 'd' 10 13

WinXP sp2 - Microsoft Visual Studio .NET 2002 version 7.0.9466
BINARY MODE
Image.size() = 21 bytes.
117 'u' 110 'n' 105 'i' 120 'x' 10 109 'm' 97 'a' 99 'c' 13
119 'w' 105 'i' 110 'n' 13 10 119 'w' 101 'e' 105 'i' 114 'r'
100 'd' 10 13
TEXT MODE
Image.size() = 20 bytes.
117 'u' 110 'n' 105 'i' 120 'x' 10 109 'm' 97 'a' 99 'c' 13
119 'w' 105 'i' 110 'n' 10 119 'w' 101 'e' 105 'i' 114 'r' 100 'd'
10 13

And here's the program:

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>

using namespace std;

int main(int argc, char *argv[])
{
if(argc != 2)
{
cerr << "Please put the name of one text file on the"
<< "command line" << endl;
exit(1);
}
#ifndef TEXTMODE
// 1
ifstream sfin(argv[1], ios_base::in|ios_base::binary );
cout << "BINARY MODE\n";
#else
// 2
ifstream sfin(argv[1]); // try this second
cout << "TEXT MODE\n";
#endif

if( !sfin.is_open() ){
cout<<"ifstream sfin FAILED"<<endl;
return 1; // EXIT_FAILURE
}
vector<unsigned char> Image;
char In(0);
while( sfin.get( In ) ){
Image.push_back( static_cast<unsigned char>( In ) );
}
sfin.close();
cout<<"Image.size() = "<<Image.size()<<" bytes."<<endl;
for( size_t i(0); i < Image.size(); ++i ){
if((i>0)&&(i%9) == 0){ cout<<endl;}
int out( static_cast<int>( Image.at( i ) ) );
cout<<setw(3)<<out<<" ";
if(out >= 32)
cout << "'" << static_cast<char>(out) << "' ";
else
cout << " ";
}
cout<<endl;
return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,280
Latest member
BGBBrock56

Latest Threads

Top