Using '\n' instead of endl affects output, why? - c++

So I made an uninitialized array in C++ and tried printing the last element to see what the output would be. Every element in an uninitialized array should have the value of 0 (right?), but the output I got was something else. This is what the main function looked like:
int main() {
int i[5];
cout << i[4] << '\n';
}
Running this outputs 1606416656 (same number every time) with a line break. However, changing '\n' to endl changes the output to 0 with a line break.
Why is that?
Also, trying to print i[3] instead of i[4] correctly outputs 0 even with '\n'. Why?
I did some research and read somewhere that '\n' doesn't "flush the buffer" while endl does. What does this "flushing the stream" actually mean, and is this what's affecting the output?

Every element in an uninitialized array should have the value of 0 (right?)
No, they have an indeterminate value. Using the values gives undefined behaviour, which is why you get unpredictable output.
What does this "flushing the stream" actually mean, and is this what's affecting the output?
When you write to the stream, the output is stored in a memory buffer, and not necessarily sent to the final destination (the console, or a file, or whatever) straight away; this can give a large performance benefit, but can also mean that you don't see the final output when you want to. Flushing the stream pushes the data you've written to the final destination.

Your assumption that an newly created array on the stack is initialized with zero does not hold. Therefore your output is random. Changing the program reorders the memory layout and so you see different results.
int main() {
int i[5];
for (int k = 0; k < 5; ++k)
i[k] = 0;
cout << i[4] << '\n';
}
should give you always the expected result regardless of using '\n' or endl

Your array remains uninitalized. Whatever value you get is coincidental. std::endl puts newline character and flushes the output stream buffer. That is the difference of std::endl manipulator and printing just a newline character.

Related

Why is cin.failbit always set even when input is valid?

I was trying to write a program that asks to input a char array using cin.getline() and if given input is bigger than array length array gets extended.
I used cin.failbit to see if user's input was too long. But nothing went right. So after debugging I figured out that the problem lies in failbit.
So I wrote a simple program to see what was wrong about it and it turned out that somehow cin.failbit always returns true when in if-statement even when input seems valid.
int main () {
char name[256];
std::cout << "Enter your name: ";
std::cin.getline (name,256, '\n');
std::cout << "characters read: " << std::cin.gcount() << std::endl;
if (std::cin.failbit){
std::cin.clear();
std::cout << "failed\n";
}
}
For example, when input is "qwer" program outputs that 5 characters have been read (cin.gcount), so it should be fine but it also outputs "fail" meaning that failbit flag is set. But I believe it shouldn't be in this case.
program output here
So can anyone explain why failbit appears to be set permanently?
Any help will be highly appreciated
std::cin.failbit is a constant that indicates which of the error bits represents stream failure. It is not an indication of the stream's current state. To check if that bit is set, use the member function std::cin.fail() instead.
However, if the stream failed to read due to reaching the end of the stream fail() will return false leading you to believe that it succeeded. Prefer std::cin.good() to check if the last operation succeeded.

Why reading from a stream does not require a buffer flush

Just started C++ learning by C++ Primer 5th ed.
The very first example of the book on page 6 is as followed
#include <iostream>
int main()
{
std::cout << "Enter two numbers:" << std::endl;
int v1 = 0, v2 = 0;
std::cin >> v1 >> v2;
std::cout << "The sum of " << v1 << " and " << v2
<< " is " << v1 + v2 << std::endl;
return 0;
}
The manipulator endl insert newline and flush the buffer.
soon followed by the code snipe in the page 7, the author emphasized that
Programmers often add print statements during debugging. Such
statements should always flush the stream. Otherwise, if the program
crashes, output may be left in the buffer, leading to incorrect
inference about where the program crashed
From the code example and the emphasized warning I feel it is important to do the flush when writing to a Stream
Here is the part I don't understand, how a bout reading from a stream case, such as std::cin, is there any necessary to do the flush then?
Appended Question:
#include <iostream>
int main()
{
int sum = 0, val = 1;
while (val <= 5) {
sum += val;
++val;
std::cout << sum << std::endl; //test
}
}
When I changed the line marked with test to std::cout << sum << '\n';, there is no visual difference in the console. Why is that, isn't it supposed to print as follows if there is no flush for each loop?
1
1 3
1 3 6
1 3 6 10
1 3 6 10 15
Thanks
Even if #Klitos Kyriacou is right when he says you should create a new post for a new question, it seems to me that both your questions arise from the same misunderstanding.
Programmers often add print statements during debugging. Such statements should always flush the stream. Otherwise, if the program crashes, output may be left in the buffer, leading to incorrect inference about where the program crashed
This quote does not mean that you need to flush every buffer in your program to create any output on the console.
By flushing the buffers you can make sure that the output is printed before the next line of code is executed.
If you don't flush the buffers and your program finishes, the buffers will be flushed anyway.
So, the reason you see the same output on the console with std::endl and \n is, that exactly the same text is printed to the console. In the former case, the output might be there slightly earlier, as the buffers are flushed early. In the latter case, the buffers are flushed later, but they will be flushed at some time.
What the quote talks about is the case when your program does not exit gracefully, e.g. when your program crashes or is interrupted by the OS. In these cases, your output might not be written to the console when you did not explicitly flush the buffers.
What the quote wants you to know is: Whenever you want to debug a program that crashes, you should explicitly flush the buffers to make sure your debug output is printed to the console before your program is interrupted.
Note that this might not be true for all implementations.
From http://en.cppreference.com/w/cpp/io/manip/endl
In many implementations, standard output is line-buffered, and writing '\n' causes a flush anyway, unless std::ios::sync_with_stdio(false) was executed.
Quote from the same book page 26:
Buffer A region of storage used to hold data. IO facilities often store input (or out-put) in a buffer and read or write the buffer
independently from actions in the program. Output buffers can be
explicitly flushed to force the buffer to be written. Be default,
reading cin flushes cout; cout is also flushed when the program ends
normally.

What does this part from the book C++ Primer 5ed mean (portion in description)? [duplicate]

This question already has answers here:
endl and flushing the buffer
(5 answers)
Closed 6 years ago.
std::cout << "Enter two numbers:";
std::cout << std:endl;
This code snippet is followed by two paragraphs and a warning note, among which I understood the first para, but neither the second one nor the note. The text is as follows -
"The first output operator prints a message to the user. That message
is a string literal, which is a sequence of characters enclosed in
double quotation marks. The text between the quotation marks is
printed to the standard output.
The second operator prints endl,
which is a special value called a manipulator. Writing endl has
the effect of ending the current line and flushing the buffer
associated with that device. Flushing the buffer ensures that all the
output the program has generated so far is actually written to the
output stream, rather than sitting in memory waiting to be written.
Warning Programmers often add print statements during debugging. Such statement should always flush the stream. Otherwise, if the
program crashes, output may be left in the buffer, leading to
incorrect inferences about where the program crashed."
So I didn't understand of the part of endl, nor the following warning. Can anyone please explain this to me as explicitly as possible and please try to keep it simple.
Imagine you have some code that crashes somewhere, and you don't know where. So you insert some print statements to narrow the problem down:
std::cout << "Before everything\n";
f1();
std::cout << "f1 done, now running f2\n";
f2();
std::cout << "all done\n";
Assuming that the program crashes during the evaluation of either f1() or f2(), you may not see any output, or you may see partial output that is misleading -- e.g. you could see only "Before everything", even though the crash happened in f2(). That's because the output data may be waiting in a buffer and hasn't actually been written to the output device.
The Primer's recommendation is therefore to flush each output, which you can conveniently achieve with endl:
std::cout << "Before everything" << std::endl;
f1();
std::cout << "f1 done, now running f2" << std::endl;
f2();
std::cout << "all done" << std::endl;
An alternative is to write debug output to std::cerr instead, which is not buffered by default (though you can always change the buffering of any ostream object later).
A more realistic use case is when you want to print a progress bar in a loop. Usually, a newline (\n) causes line-based output to be printed anyway, but if you want to print a single character for progress, you may not see it printed at all until after all the work is done unless you flush:
for (int i = 0; i != N; ++i)
{
if (i % 1000 == 0)
{
std::cout << '#'; // progress marger
std::cout.flush();
}
do_work();
}
std::cout << '\n';
Well, simply:
std::cout << "Hello world!";
will print "Hello world!" and will remain in the same line. Now if you want to go to a new line, you should use:
std::cout << "\n";
or
std::cout << std::endl;
Now before I explain the difference, you have to know 1 more simple thing: When you issue a print command with the std::cout stream, things are not printed immediately. They are stored in a buffer, and at some point this buffer is flushed, either when the buffer is full, or when you force it to flush.
The first kind, \n, will not flush, but the second kind std::endl, will go to a new line + flush.
Operating systems do buffered IO. That is, when your program outputs something, they dont necessarily put it immediately where it should go (i.e. disk, or the terminal), they might decide to keep the data in an internal memory buffer for some while before performing the actual IO operation on the device.
They do this to optmize performance, because doing the IO in chunks is better than doing it immediately as soon as there are a few bytes to write.
Flushing a buffer means asking the OS to perform immediately the IO operation without any more waiting. A programmer would do this this when (s)he knows that waiting for more data doesn't make sense.
The second note says that endl not only prints a newline, but also hints the cout to flush its buffer.
The 3rd note warns that debugging errors, if buffered and not flushed immediately, might not be seen if the program crashes while the error messages are still in the buffer (not flushed yet).

The seekp() statement seems to be unnecessary, but actually isn't

The following code works on bidirectional streams and finds the record id from file and then replaces contents for that record from the file. But before overwriting the content, it shifts the put pointer to the position of the get pointer. Through tellp()and tellg() it is found that they both were already at the same position before shifting. But on removing the seekp() line the code does not overwrite the data.
Contents in data.txt:
123 408-555-0394
124 415-555-3422
263 585-555-3490
100 650-555-3434
Code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
int inID = 263;
const string& inNewNumber = "777-666-3333";
fstream ioData("data.txt");
// Loop until the end of file
while (ioData.good()) {
int id;
string number;
// Read the next ID.
ioData >> id;
// Check to see if the current record is the one being changed.
if (id == inID) {
cout << "get pointer position " << ioData.tellg() << endl; //Displays 39
cout << "put pointer position " << ioData.tellp() << endl; //Displays 39
ioData.seekp(ioData.tellg()); //Commenting this line stops code from working
ioData << " " << inNewNumber;
break;
}
// Read the current number to advance the stream.
ioData >> number;
}
return 0;
}
Question:
What is the need of using seekp() to shift the position of the put pointer if it is already there, as the get and put pointers move together?
The question linked by #Revolver_Ocelot in the comments gives relevant information. The most important part is that you have to either flush or seek between read and write access. I therefore modified your code in the following way:
if (id == inID) {
cout << "get pointer position " << ioData.tellg() << endl; //Displays 39
cout << "put pointer position " << ioData.tellp() << endl; //Displays 39
ioData.flush();
cout << "get pointer position " << ioData.tellg() << endl;
cout << "put pointer position " << ioData.tellp() << endl;
ioData.seekp(ioData.tellg()); //Commenting this line stops code from working
ioData << " " << inNewNumber;
break;
}
This gives the following interesting output:
get pointer position 39
put pointer position 39
get pointer position 72
put pointer position 72
(Calling flush() doesn't actually resolve the problem. I just added it to your code in order to show you that it modifies the file pointer.)
My assumption on your original code is the following: If you write to your file after reading from it first, without calling seekp() in between, then the file pointer gets modified by the write command before the data is actually written to the file. I assume that the write command performs some kind of flushing and that this modifies the file pointer in a similar way as the flush() command that I added to your code.
When I ran the code above on my PC, the flush() command moved the file pointer to position 72. If we remove the seekp() command from your original code, I think that the write command will also move the file pointer to position 72 (or maybe another invalid position) before actually writing to the file. In this case writing fails, because position 72 is behind the end of the file.
Consequently, ioData.seekp(ioData.tellg()); is needed to ensure that the file pointer is set to the correct file position, because it can change when you switch between reading from and writing to your file without calling seekp().
The last paragraph of this answer gives some similar explanation.
It is because it's a rule of c++ bidirectional streams that if someone wants to shift from input operation to output operation. Then one must use seek() function to make such shift.
This functionality is borrowed from the core of c language as whenever someone uses a bidirectional stream then programmer may be working with two different buffers in which one buffer may be for input and another for output. Now synchronizing both the buffers would be a performance inefficient solution. As most of the time programmer may not need to use both the input and output functionality and program would be maintaining both the buffers for the programmer for no good reason.
So as an alternative to this, another solution was implemented to let programmer explicitly perform the flushing and other management by invoking seek() function.
Which means that seek() function that we often use does not simply repositions the file pointer but also updates the buffers and stream also.
See also
why fseek or fflush is always required between reading and writing in the read/write "+" modes

Datas from a char array well displayed while iterating to display byte by byte but not otherwise

I have a problem that I don't understand in C++:
I got a unsigned char* as a result from a method call. if I iterate the char* to display the datas everything is fine, but when I just print the datas there are not the same values displayed.
Here is my code sample:
unsigned char returning[32];
for(int i=0;i<32;i++){
returning[i] = result[i];
std::cout << returning[i];//return the good values
}
std::cout << "\n";
std::cout << returning << "\n";
//the first one are the good values, and then there are wrong
Someone could explain me this strange behavior?
tl;dr:
unsigned char returning[33];
returning[32] = '\0';
fixed.
Explanation:
The first loop will print every value in "returning". The second piece of code will only return the values until it hits a value which is zero. And then it stops, because a zero in a char array is interpreted as an end of line character.
Alternatively, if the there is no zero in "returning" anywhere, the second piece of code will continue to write random values until it does hit a zero.
First of all in returning array, you are just assigning values till 31st index which is wrong. Last byte of that should be null terminated \0.
std::cout << returning[i] This statement will read the ASCII value from that particular and it will print the corresponding character.
std::cout << returning But this statement will keep on reading bytes till it reaches \0. In your case returning array is not NULL terminated. So in this buffer overflow will happen and it will print first 32 byte proper characters and then it will start printing some other characters(may be not readable formal also). If \0 never comes in the further bytes then it will surely tries to go beyond that segment at that time application will crash.