How to print page by page with cout in C++? - c++

Imagine I have this code:
for (int i=0; i<1000; i++) {
cout << i << endl;
}
So in the console, we see the result is printed once until 999. We can not see the first numbers anymore (let say from 0 to 10 or 20), even we scroll up.
How can I print output page by page? I mean, for example if there are 40 lines per page, then in the console we see 0->39, and when we press Enter, the next 40 numbers will be shown (40->79), and so on, until the last number.

While the previously answers are technically correct, you can only break output at a fixed number of lines, i.e. at least with standard C++ library only, you have no way to know how many lines you can print before filling the entire screen. You will need to resort to specific OS APIs to know that.
UNIX people may tell you that, in fact, you shouldn't bother about that in your own program. If you want to paginate, you should just pipe the output to commands such as less or more, or redirect it to a file and then look at the file with a text editor.

You could use the % (remainder) operator:
for (int i=0; i<1000; i++) {
std::cout << i << '\n';
if(i % 40 == 39) {
std::cout << "Press return>";
std::getchar();
}
}
This will print lines 0-39, then 40-79 etc.
If you need something that figures out how many lines the terminal has and adapts to that, you could use curses, ncurses or pdcurses. For windows, (I think) pdcurses is what you should go for.
#include <curses.h>
#include <iostream>
int main() {
initscr(); // init curses
int Lines = LINES; // fetch number of lines in the terminal
endwin(); // end curses
for(int i = 0; i < 1000; i++) {
std::cout << i << '\n';
if(i % Lines == Lines - 1) {
std::cout << "Press return>";
std::getchar();
}
}
}
This only initializes curses, fetches the number of lines in the terminal and then deinit curses. If you want, you could stay in curses-mode and use the curses functions to read and write to the terminal instead. That would give you control over the cursor position and attributes of what you print on screen, like colors and underlining etc.

Related

Strange Behavior in C++ Input/Output When Parsing Large Integer Input

I have the following piece of code:
#include <iostream>
using namespace std;
int main() {
// Number of inputs
int N;
scanf("%d", &N);
// Takes in input and simply outputs the step it's on
for (int i = 0; i < N; i++) {
int Temp;
scanf("%d", &Temp);
printf("%d ", i);
}
}
When taking in a large amount of integer input, C++ stops at a certain point in printing output, seemingly waiting for more input to come.
Given an input of 2049 1's, the program stops after printing 2048 integers (0 up to 2047), and does not print the final 2048 (the 2049th integer). 2048 looks suspicious, being a power of 2.
It seems to be the case that the larger the input values, the quicker the program decides to stop, and in this case after what looks like a random number of steps. For example, I gave it 991 integers (up to the ten thousands), and the program stopped outputting after iteration 724.
Note that I copied and pasted the numbers as a whole block, rather than typing and entering them one by one, but I doubt this plays a role. I also tried cin and cout, but they did not help.
Could someone please explain the reasons behind this phenomenon?
I have found the answer to my question. The reason behind the failure is indeed due to copying and pasting large chunks of input, as many have suggested, and I thank everyone for their help. There were no incorrect characters, though, and cause of this problem is instead the 4096 character limit posed by canonical mode.
In canonical mode, the terminal lets the user navigate the input, using arrow keys, backspace, etc. It sends the text to the processor only when there is a newline or the buffer is full. The size of this buffer being 4096 characters, it becomes clear why the code fails to parse more input than that, i.e. 2049 "1 "s is 4098 characters. One can switch to noncanonical mode, which allows larger input at the expense of not being able to navigate it, using stty -icanon. Entering stty icanon takes it back to canonical mode.
Practically speaking, entering the input with newlines separating the numbers seems like the easiest fix.
This source was quite helpful to me: http://blog.chaitanya.im/4096-limit.
This post on unix stack exchange is similar to my problem: https://unix.stackexchange.com/questions/131105/how-to-read-over-4k-input-without-new-lines-on-a-terminal.
My first thought was that you're reaching some sort of barrier on the input side...
The limit for the length of a command line is not [typically] imposed by the shell, but by the operating system.
Bash Command Line and Input Limit - SO
However, this is probably not the case.
First, focus on your data, make sure your data is what you think it is (no unexpected characters) and then try to debug your reads, make sure the values are making it into memory like you intend.
Try separating out your read and write into two loops, this might help your debugging a little easier depending on your skill level, but again, making sure something funky isn't going on with your reads. Suspicion is high with the reads on this one...
Here's a couple of cracks at it below... haven't tested. Hope this helps!
#include <iostream>
int main() {
int N;
std::cin >> N;
// Read N integers, storing to array
int* numbers = new int[N];
for (int i = 0; i < N; i++) {
std::cin >> numbers[i];
}
// Print
for (int i = 0; i < N; i++) {
std::cout << numbers[i] << " ";
}
std::cout << std::endl;
// Free the dynamically allocated memory
delete[] numbers;
return 0;
}
Okay... maybe a little more optimized...
#include <iostream>
int main() {
int N;
std::cin >> N;
// fixed-size on the stack
int numbers[N];
// cin.tie(nullptr) and ios::sync_with_stdio(false) might improve perf.
std::cin.tie(nullptr);
std::ios::sync_with_stdio(false);
// Read N integers, storing to array
for (int i = 0; i < N; i++) {
std::cin >> numbers[i];
}
// Print
for (int i = 0; i < N; i++) {
std::cout << numbers[i] << " ";
}
std::cout << std::endl;
return 0;
}

Cout won't print text without endl inside while loop?

I don't know if it's related to flush in ostream. Since, endl is end with flush right? I don't know what is flush and how it works.
I have a function that will print out each characters of string every second. I want to print it out whitout new line after every characters. Then, I write this function:
using namespace std;
void print_char_per_second (string text) {
int i = 0;
int len = static_cast<int>(text.length());
while (i < len) {
int tick = clock() % CLOCKS_PER_SEC;
if (tick == 0) {
cout << text[i];
i++;
}
}
}
It prints the text one after while loop finished looping and prints all of characters in the text at once. Why this is happen?
Flushing makes sure all output written to the stream so far is shown on the console.
You can do std::cout << std::flush or std::cout.flush() after each output operation to make sure the output is shown on the console immediately.
Right now it's just writing everything to the stream and only flushing the stream after the loop.

C++ in Xcode pausing

this is my first SO post.
I am very new to programming, and with C++ I thought I might try and make a program that allows the user to submits a block of text (max 500 characters), allows them to enter a 4 letter word and the program return with the amount of times it picks that word up in the text.
I am using X-code and it keeps making a green breakpoint and pausing the program at the 'for' loop function. my code is shown below:
#include <iostream>
#include <string>
#include <math.h>
#define SPACE ' '(char)
using namespace std;
//Submit text (maximum 500 characters) and store in variable
string text;
string textQuery(string msgText) {
do {
cout << msgText << endl;
getline(cin, text); } while (text.size() > 500);
return text;
}
//Query word to search for and store as variable
string word;
string wordQuery(string msgWord) {
cout << msgWord << endl;
cin >> word;
return word;
}
//Using loop, run through the text to identify the word
int counter = 0;
bool debugCheck = false;
int searchWord() {
for (int i = 0; i < text.size(); i++) {
char ch_1 = text.at(i);
char ch_2 = text.at(i + 1);
char ch_3 = text.at(i + 2);
char ch_4 = text.at(i + 3);
cout << i;
if(ch_1 == word.at(0) &&
ch_2 == word.at(1) &&
ch_3 == word.at(2) &&
ch_4 == word.at(3) )
{
counter++;
debugCheck = true;
}
}
return counter;
}
//cout the result
int main() {
string textUserSubmit = textQuery("Please submit text (max 500 characters): ");
string wordUserSubmit = wordQuery("Please select a word to search for: ");
int counterResponse = searchWord();
cout << debugCheck << endl;
cout << "The number of times is: " << counterResponse << endl;
return 0;
}
I get the error at the for loop. Any other advice about how i can make my program work for different words, multiple lengths of words and also how i can highlight the words in text would be helpful.
I really would appreciate if someone could aid me with my problem. Thanks!
I get the error at the for loop.
You should describe the error you get. I happen to have access to Xcode so I can run your code and see what happens, but you should try to spare that of people from whom you want help.
In this case you should describe how the debugger stops the program at the line:
char ch_4 = text.at(i + 3);
includes the message: "Thread 1: signal SIGABRT" and the console output shows
libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: basic_string
Your problem is this: the for loop checks to make sure that i is in the correct range for the string text before using it as an index, but then you also use i+1, i+2, and i+3 as indices without checking that those values are also valid.
Fix that check and the program appears to run fine (given correct input).
Some miscellaneous comments.
Use more consistent indentation. It makes the program easier to read and follow. Here's how I would indent it (using the tool clang-format).
#define SPACE ' '(char) looks like a bad idea, even if you're not using it.
using namespace std; is usually frowned on, though as long as you don't put it in headers it usually won't cause too much trouble. I still could though, and because you probably won't understand the resulting error message you may want to avoid it anyway. If you really don't like writing std:: everywhere then use more limited applications such as using std::string; and using std::cout;.
global variables should be avoided, and you can do so here by simply passing textUserSubmit and wordUserSubmit to searchWord().
there's really no need to make sure text is less than or equal to 500 characters in length. You're using std::string, so it can hold much longer input.
You never check how long word is even though your code requires it to be at least 4 characters long. Fortunately you're using at() to index into it so you don't get undefined behavior, but you should still check. I'd remove the check in textQuery and add one to wordQuery.

C++ For loop loops only 299 times

I'm having this weird problem. My code is simple:
#include <iostream>
using namespace std;
int main() {
int num;
cout << "number: ";
cin >> num;
for (int i=0;num>i;i++) {
cout << i <<"\n";
}
system ("Pause");
return 0;
}
If the input for example is 1000, the output contains numbers from 701-999.
Any idea?
I'm using Dev-C++ IDE on Parallels.
Actually it prints all of them, from 0 to 999, but your console's buffer is not large enough. So you see only the last part. if you print into a file, not the console, you'll see :)
The loop ends when num>i is no longer true. This occurs when i is 1000, so the last loop executed will be with value 999. As for not seeing lower than 701, maybe your screen buffer is too small.
It will start with 0-999. Also, it appears to you that it starts with 701 because of your console screen settings. If you want to see it for yourself, change the newline into a space:
cout << i <<" ";
Did 0-700 scroll off the screen? Run your exe like this
your_program > out.txt
Then look at out.txt in an editor.
Works absolutely fine for me. I'd suggest your IDE might be playing tricks on you. Could you redirect output into a file and check that?
Regarding #JoshD answer,
You will need to:
for (int i=0;num>=i;i++) {
cout << i <<"\n";
}

Controlling output of program

I'm writing a code to output fibonacci series in C++, which is simple enough, but since I'm new to programming, I'm considering ways to control
I was wondering if there's a way to control time for when outputs come out without processing time being included (e.g. If it takes .0005 seconds to process my input and I want it to repeat the output in 1 second rather than 1.0005 seconds).
I also am wondering if there's a way to just have it output (say 1) and then have it wait for me to press enter, which will make it output the second part (2).
Also, I'd appreciate any other suggestions on how to control output.
If you're on Windows, a quick way to pause is to call system("pause"); This isn't a very professional way of doing things, however.
A way to pause with the std namespace would be something like this:
cout << "Press Enter to continue . . ." << endl;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
As for your main question... If you're just dealing with text output to the user, it's not possible for them to notice a five microsecond delay. They can notice if your interval lengths fluctuate by tens of milliseconds, however. This is why sleep(..) functions sometimes fail.
Let's take your example of wanting to output another number in the Fibonacci sequence once per second. This will work just fine:
#include <ctime>
#include <limits>
#include <iostream>
void pause() {
std::cout << "Press Enter to continue . . ." << std::endl;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
int main() {
clock_t next = clock();
int prev1, prev2, cur = 0;
for (int i = 0; i < 47; ++i) {
if (i < 2) cur = i;
else cur = prev1 + prev2;
prev2 = prev1;
prev1 = cur;
while (next > clock());
std::cout << (i+1) << ": " << cur << std::endl;
next += CLOCKS_PER_SEC;
}
pause();
return 0;
}
The next number in the sequence is computed and ready to print prior to the wait, thus the computation time will not add any delay to the timed output.
If you want your program to continue outputting at a fixed rate while your program works in the background, you'll need to look into threads. You can have your results added to a queue in one thread, while another thread checks for results to print once per second.