I am learning C++ to write a program to count how many consecutive times each distinct value appears in the input.
The code is
#include <iostream>
int main()
{
// currVal is the number we're counting; we'll read new values into val
int currVal = 0, val = 0;
// read first number and ensure that we have data to process
if (std::cin >> currVal)
{
int cnt = 1; // store the count for the current value we're processing
while (std::cin >> val)
{ // read the remaining numbers
if (val == currVal) // if the values are the same
++cnt; // add 1 to cnt
else
{ // otherwise, print the count for the previous value
std::cout << currVal << " occurs " << cnt << " times" << std::endl;
currVal = val; // remember the new value
cnt = 1; // reset the counter
}
} // while loop ends here
// remember to print the count for the last value in the file
std::cout << currVal << " occurs " << cnt << " times" << std::endl;
} // outermost if statement ends here
return 0;
}
But it won't count the last set of numbers. For example: If I have input 5 5 5 3 3 4 4 4 4, the output is:
5 occurs 5 times.
3 occurs 2 times.
The last set result which is "4 occurs 4 times." does not show up.
I wonder what is wrong with the code.
Please help.
Thanks.
hc.
Your program is correct. Your while loop will exit when the condition is false
while (std::cin >> val)
The stream input will return false when you reach end of file (EOF), which from a terminal you can enter with Ctrl-D.
Try placing your input in a file, and your program will work. I've used the cat command to copy from the terminal's standard input and redirected to a file called input. You need to press Ctrd-D to tell cat that you are done. You could also create the input file using your favorite editor.
$ cat > input
5 5 5 3 3 4 4 4 4
<press Ctrl-D here>
Now invoke the program and redirect input from the file
$ ./test < input
Output is
5 occurs 3 times
3 occurs 2 times
4 occurs 4 times
See this related question on SO
the question on while (cin >> )
You seem to generate output only when (val == currVal) is false. What makes you think this will happen after the last 4 is read from input?
Related
So I'm trying to write a program that reads unknown inputs from a data file that has a sentinel 0 or I guess an termination point for the loop.
Number of integers per line before 0 (int count).
Number of all integers in data file (int totalcount).
Number of lines in data file (int lines).
Two examples of unknown inputs from a data file:
Example One:
1 2 3 0 4 5 6 7 0
Example Two:
0 9 11 -11
1 1 0 0 2
0
Here is my program (without "count" because that is where my problem lies):
int main()
{
//Declaring variables.
int input, lines, count, totalcount, datafile;
lines = 0;
count = 0;
totalcount = 0;
//Loop runs as long as data file has an integer to take in.
while(cin >> datafile)
{
//If datafile is not 0, loop runs until datafile is 0.
while(datafile != 0)
{
//Counts all integers in the file except 0.
totalcount += 1;
cin >> datafile;
}
//Counts how many lines there are in a data file using sentinel 0 (not "/n").
if(datafile == 0)
lines += 1;
//Outputs.
cout << lines << setw(11) << count << setw(11) << totalcount << endl;
}
return 0;
}
Please do not worry about technicality, efficiency, or anything else besides the logic/concept itself as I'm just trying to find the missing link in my knowledge to complete this assignment.
With that said, my expected outputs are as formatted:
"Line #" "Counts of integers per line" "Total counts of all integers in data file"
Using example one with my current code, I would have outputs (spacing is not exact and '.' is for blanks):
1......0......3
2......0......7
Correct expected outputs:
1......3......3
2......4......7
I would like any hints or explanation of how I can count the integers per line (before sentinel 0) and assign that value to "int count" without the value persisting to the next line.
I'm a student in an introductory C++ class so please show me a basic way of how I may go about this first and then any other advanced options as necessary for future applications.
Code of Conduct Personal Statement:
By participating, you are providing necessary knowledge for assignment completion, not completing the assignment itself. The example used is generated by me intended for concept demonstration purposes and is only a small part of the final assignment.
10/23/2016 9:56PM Update 1:
Currently attempting to use a "temp" variable to substract from "totalcount". I will update my code if attempt is successful.
totalcount is sum of counts. This is my suggestion
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
//Declaring variables.
int input, lines, count, totalcount, datafile;
lines = 0;
count = 0;
totalcount = 0;
//Loop runs as long as data file has an integer to take in.
while(cin >> datafile)
{
// Add count to totalcount and reset count each time reach 0
if (datafile == 0) {
totalcount += count;
lines += 1;
cout << lines << setw(11) << count << setw(11) << totalcount << endl;
count = 0;
}
//otherwise increase count
else {
count++;
}
}
return 0;
}
The 《c++ primer 5th》1.4.4 code example is like this
#include <iostream>
int main()
{
// currVal is the number we're counting; we'll read new values into val
int currVal = 0, val = 0;
// read first number and ensure that we have data to process
if (std::cin >> currVal) {
int cnt = 1; // store the count for the current value we're processing
while (std::cin >> val) { // read the remaining numbers
if (val == currVal) // if the values are the same
++cnt; // add 1 to cnt
else { // otherwise, print the count for the previous value
std::cout << currVal << " occurs "
<< cnt << " times" << std::endl;
currVal = val; // remember the new value
cnt = 1; // reset the counter
}
} // while loop ends here
// remember to print the count for the last value in the file
std::cout << currVal << " occurs "
<< cnt << " times" << std::endl;
} // outermost if statement ends here
return 0;
}
if i input :
11
11
13
13
13
14
I think it should execute like this :
when i input
11
11
the console should show "11 occurs 2 times".
Then i can continue to input
13
13
13
then the console should show " 13 occurs 3 times".
But the result is only when i have finished typing all the number , the console output the result once . why ?
Thanks for your help .
Input from terminal is line buffered.
The first std::cin >> currVal blocks until input is available at standard input.
That doesn't happen until you press <Enter>. (Up to that <Enter>, the characters you entered are still residing in the line buffer of your terminal / CMD box. You can backspace, edit etc.; only when you press <Enter> does the terminal / CMD box actually send those characters to the program's standard input.)
For your expected behaviour to happen, try pressing <Enter> after each number.
Both std::cin >> currVal in your sample will block the standard input, std::cin means a value that comes from standard input, in that case your keyboard is your standard input.
To confirm the input from keyboard you need to push Enter key, then values are removed from the buffer of the keyboard and processed by your code.
If you want to get the values for each press of key you need to use something like std::getchar, that function reads the buffer immediately like you expect.
I am writing a very simple program to count and display the number of consecutive integers in an inputted sequence (an exercise to teach myself about while loops and conditionals). The code is as follows:
#include "stdafx.h" //obviously using VS
#include <iostream>
int main()
{
int currVal = 0, val = 0;
if (std::cin >> currVal) {
int cnt = 1; //number of consecutive values
while (std::cin >> val) {
if (val == currVal)
++cnt;
else {
std::cout << currVal << " occurs " << cnt << " times" << std::endl;
currVal = val;
cnt = 1;
}
}
std::cout << currVal << " occurs " << cnt << " times" << std::endl;
}
return 0;
}
In the last cout line, I account for the eof behavior that should exit the while loops without printing the last value. However, in VS 2015 the last line is not being printed and the while loop is apparently not terminating despite cnt no longer incrementing. The console continues running and accepts further inputs, and will actually return that last value if I enter another value or a non-integer. The final console looks like this:
And with another input:
Yet when I run the same code in an online compiler like Ideone, the result is correct and the loop terminates. http://ideone.com/mUZuh7
Is this some unusual behavior of Visual Studio, or is there some obvious beginners mistake in my code that I'm overlooking.
Thanks
You're making a mistake in your code, and as TeamEnternode points out in their answer it's unusual behaviour for Ideone.
Your while loop continue to process while there is a character to read from std::cin; however, after it reads the last 4, it increments cnt and doensn't output anything (as per your if statement). When the while loop next evaluates std::cin, there's nothing in it anymore!
Your code works as you probably expect if you don't end your input with a double (e.g. 1 2 3 4 4 5 ).
Here's what your code is doing (assume input is 1 2 3 4 4):
if (std::cin >> currVal): waits for input from std::cin. You will need to enter something in the console and press enter to get past this.
currVal is equal to 1, and the first letter from your input.
while (std::cin >> val) read another character from std::cin. This will read 2: val is now 2.
if (val == currVal): 1 is not equal to 2, so your code outputs the occurrences of 1, and changes currVal to 2.
while (std::cin >> val) read another character from std::cin. This will read 3: val is now 3.
if (val == currVal): 2 is not equal to 3, so your code outputs the occurrences of 2, and changes currVal to 3.
while (std::cin >> val) read another character from std::cin. This will read 4: val is now 4.
if (val == currVal): 3 is not equal to 4, so your code outputs the occurrences of 3, and changes currVal to 4.
while (std::cin >> val) read another character from std::cin. This will read another 4, and val will remain as 4.
if (val == currVal): 4 is equal to 4, so cnt is incremented
while (std::cin >> val) there is nothing further to read from std::cin.
If you input another different character (e.g. 5), the while loop will continue, evaluate that 5 != 4 and then output 4s occurrences and set currVal to 5. It will then try your while loop again; however, the input is once again empty.
Visual Studio is running the code correctly.
No, it's unusual behavior in the online compiler.
I'm assuming that the online compiler's standard input will only read until the end of the line, while a normal C++ program will read until end-of-file (either invalid output or the end-of-file shortcut is used), Because the while loop's condition at the end of
1 2 3 4 4
is not false. To fix your problem, you would have to read one line at a time (which you are yet to learn how to do I'm assuming), or wait to output anything at all and just save the information to a container and output everything at the end (which you are also yet to learn to do).
I can't really give you a fix in a way that you would understand. Just ignore the bug for now, and once you know more about how Standard I/O works, you can fix the bug then.
Sorry I can't be more helpful.
I am going through C++ Primer (5th ed). In section 1.4.4, there is the following example:
#include <iostream>
int main()
{
// currVal is the number we're counting; we'll read new values into val
int currVal = 0, val = 0;
// read first number and ensure that we have data to process
if (std::cin >> currVal) {
int cnt = 1; // store the count for the current value we're processing
while (std::cin >> val) { // read the remaining numbers
if (val == currVal) // if the values are the same
++cnt; // add 1 to cnt
else { // otherwise, print the count for the previous value
std::cout << currVal << " occurs " << cnt << " times" << std::endl;
currVal = val; // remember the new value
cnt = 1; // reset the counter
}
} // while loop ends here
// remember to print the count for the last value in the file
std::cout << currVal << " occurs " << cnt << " times" << std::endl;
} // outermost if statement ends here
return 0;
}
When you run it with the given input
42 42 42 42 42 55 55 62 100 100 100
It prints
42 occurs 5 times
55 occurs 2 times
62 occurs 1 times
However, in order to get the final output line
100 occurs 3 times
you must press CTRL+D. Then that is printed and the program exits.
Why is this? To me, it looks like this last line should be printed and the program exited with the others. It seems I am misunderstanding how the control flow is executed so can someone please clarify?
ps I am aware of this Incorrect output. C++ primer 1.4.4 and C++ Primer fifth edtion book (if statement) is this not correct? However, neither of these explain WHY you must ctrl+d to print the final statement.
That's because of this part:
while (std::cin >> val)
In order to terminate reading the input stream, you have to terminate it with an EOF, which is supplied by Ctrl-D.
Think about it: cin skips over whitespace by default and every time you enter a number you separate it with whitespace (a space, a tab or a newline).
How will the program ever terminate the input? The answer is when it reads an EOF character - which, as stated before, is supplied by Ctrl-D.
You must press CTRL+D because otherwise the program does not know when your stdin stream has finished. It will otherwise just sit there at while (std::cin >> val forever without terminating.
the following program is supposed to count the number of times a user inputs a integer. example: user inputs 42 42 10 10. the program is supposed to out put : 42 occurs 2 times, 10 occurs 2 times.
the problem: the code will not output the last result for the number 10 until you input another number. i have pasted the code below. this code comes from c++ primer. 1.4.4
#include <iostream>
int main()
{
// currVal is the number we're counting; we'll read new values into val
int currVal = 0, val = 0;
// read first number and ensure that we have data to process
if (std::cin >> currVal)
{
int cnt = 1; // store the count for the current value we're processing
while (std::cin >> val)
{ // read the remaining numbers
if (val == currVal) // if the values are the same
++cnt; // add 1 to cnt
else
{ // otherwise, print the count for the previous value
std::cout << currVal << " occurs " << cnt << " times" << std::endl;
currVal = val; // remember the new value
cnt = 1; // reset the counter
}
} // while loop ends here
// remember to print the count for the last value in the file
std::cout << currVal << " occurs " << cnt << " times" << std::endl;
} // outermost if statement ends here
return 0;
}
Your program as-written appears correct for a series of numeric inputs separated by whitespace.
You need to give an end-of-file indication to the program so that it will exit the while loop and print the count for the final data. In Windows, you can do that by entering [Ctrl]-[Z] as the first character on a new line. In Linux, UNIX and Mac OS X, [Ctrl]-[D] serves a similar purpose.
Alternately, you can put your set of values into a text file and use redirection to feed your program. Suppose, for example, you put your data in a file named data.txt in the same directory as your executable. In a terminal window, you can run your program as follows:
myprogram < data.txt
As some others have noted, a non-numeric input will also work in place of end of file. For example, you could enter 42 42 10 10 fred, and it'll output what you expect as well. That doesn't appear to be the intent of the program, though. For example, if you input 42 42 10 10 fred 37, the program stops at fred and won't see 37.