Counting the number of times an int appears in a file - c++

I'm making a simple program that reads in a file and a value from a user, then counters how many time that value appears in the file. I've made this so far, it compiles fine, but when you input a number, nothing happens from there. I'm stumped. Sorry if this is very basic but I can't get past this.
This is what I have so far.
#include <stdlib.h>
#include <iostream>
#include <fstream>
using namespace std;
int hold,searchnumber, counter=0;
int main()
{
cout << "This program reads the contents of a file to discover if a number you enter exists in it, and how many times. \n";
cout << "What number would you like to search for? \n";
cout << "Number : ";
cin >> searchnumber;
ifstream infile("problem2.txt");
if(!infile)
{
cout << "Can't open file problem2.txt";
exit(EXIT_FAILURE);
}
int sum=0,number;
infile >> number;
while (!infile.eof())
{
if (number == searchnumber);
counter = counter += 1;
}
{
cout << "The number " <<searchnumber << " appears in the file " << counter <<" times! \n";
cin >> hold;
}
infile.close();
}

This section contains two problems:
infile >> number;
while (!infile.eof())
{
if (number == searchnumber);
counter = counter += 1;
}
The while condition is either true or false, and if it's true, it stays so forever, and it's likely why "nothing happens". There is NOTHING in the loop that changes the state of infile.
Combine the first two lines to:
while (infile >> number)
Then you at least run through the file.
Now, this:
if (number == searchnumber);
counter = counter += 1;
Since there is a semicolon after the if-statement, you are basically saying "if it's the right number, do nothing" followed by updating the counter no matter whether you found the number or not. Remove the semicolon.
As usual, writing too much and too slowly.

You have an infinite loop at this line:
while (!infile.eof())
{
if (number == searchnumber);
counter = counter += 1;
}
You open the file and read in the lines above it, but this loop just continues until you hit eof, but since you didn't read anything else in, as long as it wasn't eof when you entered the loop it will never exit.

1.
if (number == searchnumber);
counter = counter += 1;
should be
if (number == searchnumber)
counter = counter += 1;
2.
sum is unused.

infile >> number;
while (!infile.eof())
{
if (number == searchnumber);
counter = counter += 1;
}
should be
while (infile >> number)
{
if (number == searchnumber)
counter += 1;
}
You need to read a number from the file each time before you compare. not simply do nothing in the file reading while loop.
BTW: you sum variable seems not used, remove it.

Related

Count the occurrence of numbers in C++?

I just recently created a code in C++ where I have to display the occurrence of numbers from a text file that I made using this code:
using namespace std;
int main()
{
bool isCovered[99] = {};
int number;
// Read each number and mark its corresponding element covered
while (cin.good())
{
cin >> number;
if (number == 0)
{
break;
}
if ((number >= 1) && (number <= 99))
{
isCovered[number - 1] = true;
}
}
// Check if all covered
bool allCovered = true; // Assumes all covered initially
for (int i = 0; i < 99; i++)
if (!isCovered[i])
{
allCovered = false; //Finds one number not covered
break;
}
// Display result
if (allCovered)
cout << "The tickets cover all numbers" << endl;
else
cout << "The tickets don't cover all numbers" << endl;
return 0;
}
It's not displaying a result, is the program too complex, or is it something that I'm missing?
EDIT: Thanks #selbie for the edit to my code, i was able to figure out that it was a user input but when i put in a zero for the final input. It displays the messages "The tickets don't cover all numbers", why is that?
The bug, if any, is here:
cin >> number;
while (number != 0)
{
isCovered[number - 1] = true;
cin >> number;
}
Two possible issues:
If reading from a redirected file, there's no detection of an end-of-file condition. Such would be the case if the program was invoked as program.exe < input.txt and the input.txt did not contain a 0. Without checking for eof, the program will hang when reading from an input file redirection.
Further, there's nothing to guard against bad input. i.e. numbers outside the range of [1..99]. Without guarding against out of range numbers, undefined behavior will get introduced. Or more likely, the stack will get trashed as a result of inserting into a memory address out of range.
The easy fix is this:
while (cin.good())
{
cin >> number;
if (number == 0)
{
break;
}
if ((number >= 1) && (number <= 99))
{
isCovered[number - 1] = true;
}
}

cin infinite loop when reading in a non-numeric value

I had a strange behavior in a program and I spent long time trying to deduce why. it was an infinite loop with no sense. Testing these lines of code(under suspicion) i got the same result. Every time I type in a non-numeric value such a symbol, the program runs through an infinite loop printing zeros, which i guess is how cout represents the wrong value entered. I'd like to know why is that weird behavior from cin, printing all those zeros instead of stopping when it finds a wrong reading.
#include <iostream>
using namespace std;
int main()
{
int n = 0;
while(n >= 0) {
cin >> n;
cout << n << endl;
}
return 0;
}
the program runs through an infinite loop printing zeros, which i guess is how cout represents the wrong value entered.
That is not quite right: when you ask cin for an int, but there's no int, you get no value back, but the invalid input remains in the buffer. When you ask for int again in the next iteration of the loop, same thing happens again, and no progress is made: bad data remains in the buffer.
That's why you get an infinite loop. To fix this, you need to add some code to remove bad data from the input buffer. For example, you could read it into a string, and ignore the input:
int n = 0;
while(n <= 0) {
cin >> n;
if (!cin.good()) {
cin.clear();
string ignore;
cin >> ignore;
continue;
}
cout << n << endl;
}
Demo.
You need to "eat" the non-numerical input i.e.
#include <iostream>
using namespace std;
int main()
{
int n = 0;
while(n >= 0) {
cin >> n;
if (!cin) {
char c;
cin >> c;
} else {
cout << n << endl;
}
}
return 0;
}

Simple while loop not terminating (beginner)

Here's what I want my program to do. Prompt the user to input 10 integers. Then my program adds up the even integers, adds up the odd integers, then displays both sums. Simple beginner's exercise. To do this, I'm using a while loop with a control variable. Here is the entirety of my code:
#include <iostream>
using namespace std;
int main()
{
int evenSum = 0;
int oddSum = 0;
int num;
int control = 0;
cout << "Enter 10 integers: " << endl;
cin >> num;
while (control <= 10)
{
if (num%2 == 0)
{
evenSum = evenSum + num;
}
else
{
oddSum = oddSum + num;
}
control++;
cin >> num;
}
cout << "The sum of the even integers is " << evenSum << endl;
cout << "The sum of the odd integers is " << oddSum << endl;
return 0;
}
To test this code, I'm using as input the first 10 positive integers, 1-10. However, I'm having a couple headaches. First, control never passes from the while loop, i.e. the program never gets to the point where it displays the evenSum and outSum variable values. I'm having a hell of a time figuring out why the while loop never terminates. As I've written it, the while condition will become false as soon as control = 11, and the control variable is incremented at the end of the while body, so it should not keep going. Yet it does.
My second headache (probably related) is that the sum of the even numbers in my input should be 30, and the sum of the odd numbers should be 25. However, while my program gets the oddSum correct, it only sums the evens up to 20, so it is not counting the last number (10) for some reason.
I have walked through this program carefully several times on paper. Also, I've had it display the variable values as it goes, so I can track what it is doing with each while loop. Eventually, it just stops displaying output, but without ever actually terminating. And it sums the evens and odds correctly, just without adding that last number.
It seems to me there is at least one off-by-one error here, possible 2 that are compounding each other. But I have tried adjusting my various values and it's nothing doing. My other thought is that I'm suspicious of the way I have set up my input stream. I.e. I'm unsure of what value will be assigned to num in the final iteration of the while loop.
Can anyone shed some light on either of these problems?
Read at the top of your loop (after checking the count)
// cin >> num;
while (control <= 10)
{
cin >> num;
if (num%2 == 0)
{
evenSum = evenSum + num;
}
else
{
oddSum = oddSum + num;
}
control++;
// cin >> num;
}
Try to trace the code execution. Manually. That is the best way to learn how computers think.
You’ll realize, that the loop condition is broken. You start counting from 0, continue up to 10 including, stop at 11. 0..10, that’s 11 numbers!
Furthermore, you are reading input once at the beginning and then once at the end of each iteration. That makes 12 reads.
When trying to read more input than supplied, the program blocks and waits for more input. A program in infinite loop is active, it consumes all your CPU resources. In this case the program is blocked and uses close to no resources.
ask to enter numbers inside the loop,its easy to understand when to input particular number
int control = 1;
while (control <= 10)
{
cout << "Enter integer at position:"+Control << endl;
cin >> num;
if (num%2 == 0)
{
evenSum = evenSum + num;
}
else
{
oddSum = oddSum + num;
}
control++;
}
I could not see an error. Only the issue that you have to put 11 numbers instead of 10. Have you tried to type 11 numbers?
hey i am also a beginner but i tried to answer your question. you could also use compound assignment i.e. += instead of repeating evenSum and oddSum twice.
#include <iostream>
using namespace std;
int main()
{
int evenSum = 0;
int oddSum = 0;
int num;
int control = 0;
cout << "Enter 10 integers: " << "\n";
while (control <= 9 )
{
cin >> num;
if (num % 2 == 0)
{
evenSum += num;
}
else
{
oddSum += num;
}
control++;
}
cout << "The sum of the even integers is: " << evenSum << "\nThe sum of the odd integers is: " << oddSum << "\n";
return 0;
}

While won't start loop after y/n input C++

Problem: while doesn't work to start loop over when user inputs y.
I have spent hours searching all forums including Stack Overflow for a clue and tried to figure this out (learning C++ on my own). Based on what I have read I have tried: a do loop works when placed at beginning but it incorrectly calculates by multiplying prior numb entry by next entry factorial (flushing problem?), I tried break and it stops calculation but it also stops without getting to cout <<“Do another?”. I have also tried adding/moving braces around statements and if statements (in desperation).
//problem #6 page 127 Robert Lafore OOP Prg C++ 4th ed.
#include <iostream>
using namespace std;
int main()
{
unsigned int numb;
unsigned long fact = 1; //long for larger numbers
char ch;
cout << "Enter a number ";
cin >> numb;
for (int j = numb; j > 0; j--) //multiply 1 by
{
fact *= j;
cout << "Factorial is "<< fact << endl;
cout << "Do another? (y/n)\n";
cin >> ch;
}
while(ch !='n');
return 0;
}
Your logic isn't quite right - you need to perform the operation once, then ask, and redo the entire operation.
Right now, you do a for loop for your operation, then get the character the user types every loop iteration, then just start a while loop that never terminates.
do/while is a good candidate for this:
do
{
fact = 1; // Reinitialize for subsequent loops
cout << "Enter a number ";
cin >> numb;
for(int j = numb; j > 0; j--) //multiply 1 by
{
fact *= j;
}
cout << "Factorial is " << fact << endl;
cout << "Do another? (y/n)\n";
cin >> ch;
}
while (ch == 'y'); // Switched to make anything other than 'y' break out
You need to do this:
do
{
for(int j=numb; j>0; j--) //multiply 1 by
{
fact *=j;
}
cout <<"Factorial is "<< fact<<endl;
cout <<"Do another? (y/n)\n";
cin >> ch;
}
while (ch != 'n');
What's wrong:
Your code goes into a for loop:
for(int j=numb; j>0; j--)
It calculates the factorial...but the code to do another one is in the for loop! Your program flow is like this:
Enter the for loop
Multiply fact by j and store the value in fact
Print the value of fact
Ask to do another
Store the value in ch
Continue the for loop
See the problem? You are asked to do another for each iteration of the for loop. Then, the while loop does this:
Loop while ch isn't equal to 'n'.
But...the loop is infinite! After the last iteration of the for loop, ch doesn't change. So, if the last value was 'y', well, the while loop keeps on looping over...and over...and over...since it has no body, it just continues forever.
You have sort of the right bits of code, but the bits of code are in the wrong places.
Move the output and input for "Do Another" to after the for-loop.
Add do { before cout << "enter a number;`
Add '} beforewhile(ch != 'n');`
Right now, you have a forever loop when ch is not 'n', since nothing changes ch inside the actual loop.

Problem with reading from file causing infinite loop

Ok this program I am working on seems to be all ok except there is a problem. Here is the code
#include <iostream>
#include <fstream>
using namespace std;
/*
Function Name: CalculateBinary
CalculateBinary takes a number from the main function and finds its binary form.
*/
void CalculateBinary( long InputNum)
{
//Takes InputNum and divides it down to "1" or "0" so that it can be put in binary form.
if ( InputNum != 1 && InputNum != 0)
CalculateBinary(InputNum/2);
// If the number has no remainder it outputs a "0". Otherwise it outputs a "1".
if (InputNum % 2 == 0)
cout << "0";
else
cout << "1";
}
void main()
{
// Where the current number will be stored
long InputNum;
//Opens the text file and inputs first number into InputNum.
ifstream fin("binin.txt");
fin >> InputNum;
// While Input number is not 0 the loop will continue to evaluate, getting a new number each time.
while (InputNum >= 0)
{
if(InputNum > 1000000000)
cout << "Number too large for this program ....";
else
CalculateBinary(InputNum);
cout << endl;
fin >> InputNum;
}
}
Here is the text file I am reading in
12
8764
2147483648
2
-1
When I get to 8764, it just keeps reading in this number over and over again. It ignores the 2147483648. I know I can solve this by declaring InputNum as a long long. But I want to know why is it doing this?
That is the usual problem with such loops which you've written.
The correct and the idiomatic loop is this:
ifstream fin("binin.txt");
long InputNum;
while (fin >> InputNum && InputNum >= 0)
{
//now construct the logic accordingly!
if(InputNum > 1000000000)
cout << "Number too large for this program ....";
else
CalculateBinary(InputNum);
cout << endl;
}
That number is too large for a long to store, so fin >> InputNum; does nothing. You should always read as while(fin >> InputNum) { ... }, as that will terminate the loop immediately on failure, or at least check the stream state.
It would appear that the long type on your platform is 32 bits wide. The number 2147483648 (0x80000000) is simply too large to be represented as a signed 32-bit integer. You either need an unsigned type (which obviously won't work with negative numbers) or a 64-bit integer.
Also, you should check whether the read is successful:
...
cout << endl;
if (!(fin >> InputNum)) break; // break or otherwise handle the error condition
}
You don't check for EOF, thus being trapped in a loop forever. fin >> InputNum expression returns true if succeeded, false otherwise, so changing you code to something like this will solve the problem:
while ((fin >> InputNum) && InputNum >= 0)
{
// ...
}