Problem with reading from file causing infinite loop - c++

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)
{
// ...
}

Related

While condition: How to allow comparison between non-integer/double user input and integer limits

Objective: Run a while loop that will repeat until the user inputs an integer between 1-3 (inclusive). So if an integer that is smaller than 1 or bigger than 3 is inputted or any character or string is inputted, the loop repeats.
My noob knowledge: I know how to compare user input when it is an integer, but when it is a char or string datatype input all I get is an infinite loop. Plus I declared the inputtable variable as an integer, so not sure how to go on about this.
I've done some Google searches but can't seem to find a question similar enough to mine.
Advice is highly appreciated :)
Code below:
int Decision1 = 4;
while ( Decision1 < 1 || Decision > 3)
{
std::cout << "Enter answer here: ";
std::cin >> Decision1;
std::cout << "\n\n";
}
int Decision1;
while(std::cin >> Decision1) {
if(Decision1 >= 1 && Decision1 <= 3) break;
// todo
}
You can use ASCII codes for checking number or character.
#include <iostream>
int main() {
char Decision1 = '0';
while ( (Decision1 < 49 && Decision1 >=47) || (Decision1 >51 && Decision1 <=57 ))
{
std::cout << "Enter answer here: ";
std::cin >> Decision1;
std::cout << Decision1;
std::cout << "\n";
}
}
I hope helpful for you.
Keep in mind: when you read input from std::cin you're reading text that's typed at the console. The stream extractor tries to convert that text to the target type. That is, in
int i;
std::cin >> i;
the >> operator looks for digit characters and figures out what value those characters represent. If the characters can't be converted to an integer value the extraction fails. Streams have a conversion to bool that tells you whether the stream is in a good state, or whether an attempted operation failed. So:
int i;
if (std::cin >> i)
std::cout << "got a value!\n";
To write a loop that prompts for valid input you need to reverse the test:
int i;
while (!(std::cin >> i) {
std::cout << "bad input\n":
// now clear the input stream, so it's back in a good state
}
To also check that the value is in the required range, just do it:
int i;
while (!(std::cin >> i) || i < 1 || i > 3) {
std::cout << "bad input\n":
// now clear the input stream, so it's back in a good state
}
To clear the input stream, you have to reset its internal flags. You do that with std::cin.clear();. And, depending on what you think was typed in, you probably want to get rid of any additional characters that the user typed. You do that with std::cin::ignore(std::numeric_limits<std::streamsize>::max(), '\n'). That tells the stream to discard character until it reaches a newline (press ENTER), or until it has read a huge number of characters.
Putting it all together:
int i;
while (!(std::cin >> i) || i < 1 || i > 3) {
std::cout << "bad input\n":
std::cin.clear();
std::cin::ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Yes, this clears the stream state and flushes the input when the input was a valid integer but out of range; that's harmless. It's a waste of time, but the speed of keyboard input is limited by how fast the user types, which is much slower than anything that the code in this loop does.

trying to output all odd numbers from a sentinel loop, almost got it but not quite and also want to know why I am doing what needs to be done

Hi so I have to write this program, Write a sentinel controlled while loop.
Ask user to input integer numbers. Output all odd numbers. Program quits when the value:
-999 is entered. I have most the program functioning correctly except inputting multiple numbers and outputting only odd numbers, I created the program below and it quits the program at -999 and asks for input and outputs odd numbers, but I have tried to get it to do what the program requires and have been having issues getting it to input multiple integers and outputting just the odd ones. My program is posted below
#include <iostream>
using namespace std;
int main()
{
const int SENTINEL = -999;
int num;
cout << "Enter a number to stop enter -999 " << endl;
cin >> num;
while (num != SENTINEL)
{
if (num % 2 != SENTINEL)
cout << "odd integer is: " << num << endl;
cout << " Enter a number " << endl;
cin >> num;
}
return 0;
}
to test if num is an odd, use:
if (num % 2) instead of if (num % 2 != SENTINEL)
because the remainder is calculated when divided by 2 using the % modulus operator, if it isn't zero this integer is odd, your test != SENTINEL doesn't really make sense.

Counting the number of times an int appears in a file

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.

Issue with Infite Loop

I have a problem. This code is not giving the results it should. It should out number to large to the console and for some reason it is ignoring the if the statement when doing this. Also, in this program InputNum should remain of the long data type.
#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 = 3000000000;
//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;
}
}
CalculateBinary(InputNum) does NOT modify the value of InputNum, so its value would be always the same (300000000) and the while loop never end.
The if statement is not being ignored; you just aren't modifying InputNum. Its always going to keep its initial value. You are passing InputNum by value, not by reference. Therefore, CalculateBinary() is using a copy of InputNum.
Yes, it will be infinite. That's because you have a:
while (InputNum >= 0)
line in main but you never change the value of InputNum!
Remove the while loop altogether. It looks like you may need it when you start reading your numbers in from binin.txt but certainly not yet.
Looks like you are expecting the last number in the file to be less than 0 to terminate your program. Instead it's better to detect the end of the file. Try uncommenting your file code and using the while condition instead:
while (fin.good())

Problem with input in c++

I have a very basic question i want to take integer input in certain range from user. if the user gives some string or char instead of integer. then my program goes to infinite loop.
my code is some what like that
cin >> intInput;
while(intInput > 4 || intInput < 1 ){
cout << "WrongInput "<< endl;
cin >> intInput;
}
I am only allowed to use c++ libraries not the c libraries.
As mentioned in the possible duplicate, you should check the state of cin on each loop.
Possible implementation:
if(cin >> intInput)
while(intInput > 4 || intInput < 1 ){
cout << "WrongInput "<< endl;
if(!(cin >> intInput)){ break; }
}
Very ugly code, just trying to illuminate the answer which is to check the state of cin.
The solution to this answer is to always read lines from the standard input.
std::string input; int value = 0;
do
{
// read the user's input. they typed a line, read a line.
if ( !std::getline(std::cin,input) )
{
// could not read input, handle error!
}
// attemp conversion of input to integer.
std::istringstream parser(input);
if ( !(parser >> value) )
{
// input wasn't an integer, it's OK, we'll keep looping!
}
}
// start over
while ((value > 4) || (value < 1));
#include <locale>
..
if(!isalpha(intInput)) {
..
}
Note, this won't work if, for example the user enters a "+" but maybe it will put you in the right direction..