I found this code on a q&a platform.
#include <iostream>
int main()
{
for (int i = 0; i < 300; i++)
std::cout << i << " " << i * 12345678 << std::endl;
}
At first sight, this seems normal but instead it runs infinitely.
Results at : https://ideone.com/7F88MV
Now I changed the std::endl to "\n" and it behaved normal this time running for 300 times, terminating at i=299.
So what is going on with the std::endl keyword ?
Related
This question already has answers here:
"std::endl" vs "\n"
(10 answers)
Closed 1 year ago.
I am trying to understand buffer, endl vs \n and why the latter is more efficient than endl.
Specifically, I am reading this
https://www.geeksforgeeks.org/buffer-flush-means-c/
The following code is supposedly output 1,2,3,4,5 at once
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
for (int i = 1; i <= 5; ++i)
{
cout << i << " " ;
Sleep(300);
}
cout << endl;
return 0;
}
whereas the following will output each integer one at a time:
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
for (int i = 1; i <= 5; ++i)
{
cout << i << " " << flush;
Sleep(300);
}
return 0;
}
However, both looks exactly the same during the time of execution, they appear one a time. Is my understanding wrong?
I'm also confused why endl is less efficient compared to \n.
From what I read, endl adds a \n and then flushes.
Isn't this more efficient, since it waits for the buffer to be full then output everything at once, compared to \n?
Please correct my flawed understanding, thank you.
You will clearly see the difference if you run the following code:
#include <iostream>
#include <unistd.h>
using namespace std;
int main()
{
for (int i = 1; i <= 5; ++i)
{
cout << i << " " << flush;
usleep(300000);
}
cout<<"\n";
for (int i = 1; i <= 5; ++i)
{
cout << i << " " ;
usleep(300000);
}
cout << endl;
return 0;
}
std::endl is equivalent to using "\n" and flush together.
If your program is stable then simply use "\n" else go for std::endl. "\n" is more efficient in terms that it does not force the buffer to be flushed right then.
Also in your code, you might now be able to see the difference because you are using Sleep() which takes input in milisec, so try with greater value.
How to clear content in a simple way?
If I use vec_vec.clear(); only, there is still something in the vector that has not been cleaned up.
#include <iostream>
#include <vector>
int main()
{
std::vector<std::vector<int>> vec_vec(10);
vec_vec[0].push_back(1);
vec_vec[0].push_back(2);
vec_vec[0].push_back(3);
vec_vec[0].push_back(4);
for (auto i : vec_vec[0])
std::cout << i << " ";
std::cout << "." << std::endl;
vec_vec.clear();
for (auto i : vec_vec[0])
std::cout << i << " ";
std::cout << "." << std::endl;
vec_vec[0].clear();
for (auto i : vec_vec[0])
std::cout << i << " ";
std::cout << "." << std::endl;
for (int i=0; i<vec_vec.size(); i++)
vec_vec.erase(vec_vec.begin() + i);
for (auto i : vec_vec[0])
std::cout << i << " ";
std::cout << "." << std::endl;
return 0;
}
1 2 3 4 *
0 0 3 4 *
*
*
vec_vec.clear();
for (auto i : vec_vec[0])
After this clear, vec_vec is empty, so the expression vec_vec[0] has undefined behavior.
Undefined behavior means anything at all might happen, and it's the fault of the program, not the fault of the C++ compiler, library, etc. So it might act like an empty vector, it might crash your program, it might print some values, or it might do what you expect today, then break at the worst possible time later on.
See also this Q&A on Undefined, unspecified, and implementation-defined behavior.
On both windows and linux I am using Geany IDE and writing a c++ program. For some reason right now it is not catching an error on either linux/windows. I am using EXIT_SUCCESS and need to have the header file , right? also using copy function and it requires ? It only stops when I exclude and I discovered this because in my code I left it out by accident but it compiled, built and ran just fine.
It catches it when I use just G++, I'm not sure what is going on, could it be some setting I have in Geany?
Here is the code I'm working with
#include <iostream>
#include <algorithm>
#include <cassert>
//~ #include <cstdlib>
int main()
{
int xSize = 10;
int ySize = 50;
int xData[xSize];
int yData[ySize];
for(int i = 0; i < xSize; ++i) {
xData[i] = i;
std::cout << " First X Array value: "<< xData[i] << " " << std::endl;
}
std::cout << std::endl;
for(int i = ySize; i >= 0; --i) {
yData[i] = i;
std::cout << " First Y Array value: "<< yData[i] << " " << std::endl;
}
std::cout << std::endl;
std::copy(xData, xData+6,yData+42);
std::cout << "The copy function added it's first 6 values to the yData array starting at Y's 42nd array position" << std::endl;
for (int i = 42; i < ySize; ++i) {
std::cout << "First array value of Y is now: " << yData[i] << std::endl;
}
assert(yData[42]==0);
return EXIT_SUCCESS;
}
Thanks!
I have an existing program that contains a loop over files. It does various things, providing lots of terminal output. I want to have an overall progress bar that remains stationary on the same line at the bottom of the terminal while all of the output from the file operations is printed above it. How should I try to do something like this?
EDIT: So, just to be clear, I'm trying to address the display problems inherent in something a bit like the following:
#include <unistd.h>
#include <iostream>
#include <string>
using namespace std;
int main(){
for (int i = 0; i <= 100; ++i){
std::cout << "processing file number " << i << "\n";
string progress = "[" + string(i, '*') + string(100-i, ' ') + "]";
cout << "\r" << progress << flush;
usleep(10000);
}
}
The only portable way of moving the cursor around that I know of is using \r to move to the beginning of the line. You mention that you would like to output stuff above the progress. Fortunately, you are in luck since you're on Linux and you can use the terminal escape codes to move around the terminal freely. Look at this example:
#include <unistd.h>
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << endl;
for (int i=0; i <= 100; ++i)
{
string progress = "[" + string(i, '*') + string(100-i, ' ') + "]";
cout << "\r\033[F" << i << "\n" << progress << flush;
usleep(10000);
}
}
Here, I added the ability to print the progress value above the progress bar by moving to the beginning of the line using \r and one line up using escape code \033[F before printing. Then, printed one line, moved down one line with \n
and re-printed the progress.
You can go even further and move your cursor to any X,Y position in the terminal before printing. For that use the escape code \033[Y;Xf before your output.
For a good list of escape codes, check out Wikipedia: https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_codes
So, it is possible to achive that behavior without using additional libs like ncurses, but maybe it is actually what you want if you intend to create a more gui-like experience.
Fixing your attempt:
void print_progress_bar(int percentage){
string progress = "[" + string(percentage, '*') + string(100 - percentage, ' ') + "]";
cout << progress << "\r\033[F\033[F\033[F" << flush;
}
int main(){
cout << endl;
for (int i=0; i <= 100; ++i){
std::cout << "processing file number " << i << "\n";
std::cout << " doing thing to file number " << i << "\n";
std::cout << " doing another thing to file number " << i << "\n";
print_progress_bar(i);
usleep(10000);
}
cout << endl;
cout << endl;
cout << endl;
cout << endl;
}
I'm using the following short program to test std::clock():
#include <ctime>
#include <iostream>
int main()
{
std::clock_t Begin = std::clock();
int Dummy;
std::cin >> Dummy;
std::clock_t End = std::clock();
std::cout << "CLOCKS_PER_SEC: " << CLOCKS_PER_SEC << "\n";
std::cout << "Begin: " << Begin << "\n";
std::cout << "End: " << End << "\n";
std::cout << "Difference: " << (End - Begin) << std::endl;
}
However, after waiting several seconds to input the "dummy" value, I get the following output:
CLOCKS_PER_SEC: 1000000
Begin: 13504
End: 13604
Difference: 100
This obviously doesn't make much sense. No matter how long I wait, the difference is always somewhere around 100.
What am I missing? Is there some header I forgot to include?
I'm using Xcode with GCC 4.2.
clock() counts CPU time, so it's not adding any time if it's sitting around waiting for input.