Issue with Infite Loop - c++

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())

Related

Validating Integer input using booleans

In my c++ code, I would like to validate my user input to be an int between 1,10 using a do while loop. I am able to validated for integers outside of the range. However if user inputs a float or a letter, it becomes an infinite loop. My idea is to add a condition in my while loop for if the input is not an integer to keep asking for input.
the CAPITAL letters is where I am having trouble.
#include <iostream>
using namespace std;
int main(){
cout << "Welcome, ";
int steps;
int count=0;
do{
cout << "How many? \n";
cin >> steps;
IF (STEPS IS NOT INTEGER==TRUE){
COUNT=1;
}
if (steps <1)
{
cout << "not enough...\n";
}
if (steps > 10){
cout << "too many steps.\n Please pick a lower number of steps.\n\n";
}
} while (steps < 1|| steps >10 || COUNT==1);
//doing stuff with valid input
return 0;
}
Essentially I am trying to add another condition that just returns a boolean. and if the boolean implies that the input is not valid, then it reassigns count to make sure the do while loops continues until the input is valid.
The problem i am working on asks for a max and min steps, since all of them were having a similar problem i tried to simplify it and forgot some of the edits.
You can check whether the input failed, i.e. the user entered something that could not be read as an int like this:
if (cin.fail()) { // in place of IF (STEPS IS NOT INTEGER==TRUE)
cin.clear();
cin.ignore();
cout << "not an integer, try again\n";
continue;
}
This avoids the need for the COUNT variable.
Also, your while condition doesn't appear to match the checks inside the loop. What happens when step is either 9 or 10? You should be consistent with the checks inside the loop.
You could use the ! operator.
For example:
if ( !(std::cin >> steps) )
{
std::cin.clear();
std::cin.ignore();
std::cout << "Incorrect entry. Try again: ";
}
Also consider not using using namespace std;.

I want it to select even numbers and tell me if it greater than a certain number. I want multiple conditions in my switch statement in my C++ program

I want the program to read my file. I want to count all the numbers in the document that are greater than 175 and that are even using a switch statement. Or is there any better way to do it? Also wanting to know where I can get help with learning C++ since I am new to this? This is what I came up with but my program seems to not execute. This part of a bigger coding program. I want to know if it is possible to create multiple commands in the switch statement. I need help with case 0 on switch(num%2).
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
int main ()
{ //Listing all my variables
int num;
double even;
int evencount = 0;
int evencountext = 0;
double big;
int bigcount = 0;
double sm;
int smcount = 0;
double odd;
int oddcount = 0;
double small;
double large;
double average;
double total;
int amount = 0;
string filename;
ifstream inFile; //Input and output data from a file
ofstream outFile;
inFile.open("integers.dat"); //Open the integers.dat
if (!inFile) //Closes if the program does not exist.
{
cout << "No File Found! Closing Program." << endl;
return 1;
}
cout << "Welcome to Wake's Integer Processing Agency \n" << endl; //First line of output
cout << "What is the name of your file? "; //Get the name of the file from user
cin >> filename;
cout << endl;
inFile >> num; // Get the first number from the file
large = num; // Copy the number to the large and small variables to give the number something
small = num; // to compare them to.
while (inFile) //Main loop designed to grab numbers continuosly until the file ends.
{
switch (num % 2) //This switch divides the each number in the file by two and examines the remainder
{
case 0: // If the remainder is zero, this means the number is even
evencount++; // Increase the counter for even by one
if(num >= 175)
{evencountext++;};
even = even + num; // And the even number to the variable for total even numbers
break;
case 1: // If remainder is positive or negative one, this means the number is odd
case -1:
oddcount++; // Increase total odd numbers by one
odd = odd + num; // Add the odd number to the variable for total odd numbers
}
cout << evencountext<< endl;
cout << "The sum of the odd integers is " << odd << endl;
inFile.close(); //close the integers.dat file
return 0; //close program
}
}
It is better to use if statement remainder could be anything
if (num % 2 == 0){ // If the remainder is zero, this means the number is even
evencount++; // Increase the counter for even by one
if(num >= 175){
evencountext++;
even = even + num; // And the even number to the variable for total even numbers
}
}else{ // If remainder is not zero, this means the number is odd
oddcount++; // Increase total odd numbers by one
odd = odd + num; // Add the odd number to the variable for total odd numbers
}
Switches and if/else are flow control tools. If/else statements evaluate true/false, whereas switches require integer inputs and tests it against other values; uniformly.
Since you want to run multiple tests per data, I recommend that you store the data acquired into a (temporary) variable so you apply whatever multiple tests you need.
Like others have posted you should use if statements when testing for truths, and switches when testing for matches.
As for tutorials:
My default two recommended:
Tutorial spot:
https://www.tutorialspoint.com/cplusplus/cpp_basic_syntax.htm
CPlusPlus:
http://www.cplusplus.com/doc/tutorial/program_structure/
Code relative to original post:
#include <iostream>//Used for c++ Standard I/O stream
#include <fstream>//Used for c++ File I/O stream
//using namespace std;//Adding this will no longer require you to type any std::
//using std::cout;//Adding this will no longer require you to type std:: in front of cout
//using std::cin;//Adding this will no longer require you to type std:: in front of cin
//using std::fstream; " " "
int main()//Main Function:
{
//Declare and initialize fstream for input operations
std::fstream fs ("file.txt", std::fstream::in);//Open file for reading
//Declare integer variables and provide default values for accumulators/totals.
int large, small, num, even = 0, odd = 0, evenSum = 0, oddSum = 0;
//Declare boolean to test against first run; embedded initialization within loop.
bool first = true;
while(fs >> num) {//DATA stored into variable num.
//Print the number out for debugging (visual reading without debugger).
std::cout<<"The number: "<<num<<std::endl;
//Initialize our smallest number and largest number if not done so already.
if(first) {//Only occurs the first run
first = false;//Disables this test from here on.
small = large = num;
}
//Test if the number is larger than our largest.
if(num > large) {
large = num;
}
//Test if the number is smaller than our smallest.
if(num < small) {
small = num;
}
//Test if the number is 0 or 1. (0 and 1 are false and true, but not really).
if(num%2 == 0) {//If even:
++even;//Increment counter PRE
evenSum+=num;//Accumulate the total even values.
}else {//Else, were assuming it is odd (without having to check again).
odd++;//Increment counter POS; doesn't matter here
//but it does matter if on the stack.
oddSum+=num;//Accumulate the total odd values.
}
}//The end of the while loop. It retests the loop until satisfied.
//In a PRE loop it would leave the loop when false occurs.
//Make sure to always close the file after you're done using it.
fs.close();
//Printing the data:
std::cout<<"Number of even numbers: "<<even<<std::endl;
std::cout<<"Number of odd numbers: "<<odd<<std::endl;
std::cout<<"Sum of even numbers: "<<evenSum<<std::endl;
std::cout<<"Sum of odd numbers: "<<oddSum<<std::endl;
std::cout<<"Largest number: "<<large<<std::endl;
std::cout<<"Smallest number: "<<small<<std::endl;
//std::end produces newline and does some sub-procedure in clearing buffers.
return 0;
}
Sample Output:
The number: 123
The number: 456
The number: 222
The number: 21
The number: 1
The number: 50
The number: 22
Number of even numbers: 4
Number of odd numbers: 3
Sum of even numbers: 750
Sum of odd numbers: 145
Largest number: 456
Smallest number: 1
Sample Input:
123 456 222
21
1
50
22 a
d
55

Why "keep_window_open()" doesn't wait for a character to be entered?

I'm new to programming, and I'm trying to learn C++ by myself, and I'm following "Programming principles and practice using C++".
I was trying to do an exercise that, after various other steps, asked me to
" ...change the body of the loop so that it reads just one double each time around. Define two variables to keep track of which is the smallest and which is the largest value you have seen so far. Each time through the loop write out the
value entered. If it’s the smallest so far, write the smallest so far after the number. If it is the largest so far, write the largest so far after the number".
I wrote the following code so far:
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
inline void keep_window_open() { cout<<"\nType a character to exit: "; char ch; cin>>ch; }
int main()
{
double val1 = 0, smallest = 0, largest = 0;
int flag = 0;
while (cin >>val1) {
if (val1=='|')
break;
else
cout <<val1 <<'\n';
if (flag==0) {
smallest = val1;
cout <<smallest <<" it's the smallest value so far.\n";
}
if (val1<smallest) {
smallest = val1;
cout <<smallest <<" it's the smallest value so far.\n"; }
else if (val1>largest) {
largest = val1;
cout <<largest <<" it's the largest value so far.\n"; }
++flag;
}
keep_window_open();
return 0;
}
My problem is that when I input a character, e.g. 'c', the program ends, although the program should end, hypothetically, only when I enter '|', and I get:
c
Type a character to exit:
Process returned 0 (0x0) execution time : ...
Press any key to continue.
and "keep_window_open()" doesn't wait for a character to be entered. I just can't understand what happens, and why. Does anyone have a clue?
Well, I think the problem is in the way you defined your loop expression.
Neither cin nor its operator ">>" return a true / false value that you can work with. They return an iStream object which could be a dubious translation to true or false via an automated casting that happens behind the curtains. They will however return null when the input cannot be set inside your variable like in the case of trying to put 'c' into a double, and null translates into false.
What I suggest for you is to create a simple while(true) loop and when you get the "|" character from the user(as a string) you break the loop. until then the loop continues. then inside the loop parse your value and work on it according to your logic(minimum / maximum)
Problem
while (cin >>val1) reads input into a double. If you input something that cannot be read as a double like "|" then this will fail and cause your loop to exit.
You then try to read more input while cin is in an error state.
Solution
Call cin.clear() to first clear any error flags and then cin.ignore(1000, '\n') to throw away anything left hanging in the input stream.
inline void keep_window_open()
{
cout << "\nType a character to exit: ";
char ch;
cin.clear();
cin.ignore(1000, '\n');
cin >> ch;
}
Note
if (val1=='|')
break;
This code will never be true because if you try to input the pipe character your while loop will fall through before ever getting to it.

Using an array of counters extract the integers from a file and count the number of responses?

#include <iostream>
#include <fstream>
#include <windows.h>
using namespace std;
void addRecordstoFile();
void readRecordsFromFile();
int main(){
addRecordstoFile();
readRecordsFromFile();
}
void addRecordstoFile(){
This adds the integers to the file but I want when it exits (when the user enters -1) not be displayed in the .txt file
int num=1;
char response;
ofstream outFile("numbers.txt",ios::out);
if (!outFile){
cerr<<"File was not opened correctly"<<endl;
exit(1);
}
cout<<"\t\t\tSurvey Response Analyzer"<<endl;
while(num!=-1){
cout<<"\n Enter a survey response from 1 to 10 (-1 to end): ";
cin>>num;
if(num<1 || num>10){
cout<<"\n Please enter a valid response from (1-10): ";
cin >>num;
}
outFile << num <<" ";
}
outFile.close();
cout<<"Saved to file..."<<endl;
system("pause");
}
This is where the major problem lies, I should extract the integers from the text file and place them in an array of counters to count the number of times the user enterred a number between 1 and 10. I am completely lost because I would need the size of the array to determine my loop.
void readRecordsFromFile(){
ifstream inFile("numbers.txt",ios::in);
if(!inFile){
cerr<<"File was not found";
exit (1);
}
How can I make an array of counters here without knowing the size of the array from the text file?
1. First query:
This adds the integers to the file but I want when it exits (when the
user enters -1) not be displayed in the .txt file
Replace
if (num < 1 || num > 10) {
cout<<"\n Please enter a valid response from (1-10): ";
cin >>num;
}
outFile << num <<" ";
with
if (num < 1 || num > 10) {
cout<<"\n Please enter a valid response from (1-10): ";
cin >>num;
} else {
outFile << num <<" ";
}
2. Second query:
I would need the size of the array to determine my loop
No you don't. You may use a while loop to check the end.
1st thing first, in your void addRecordstoFile() function, you could design your while loop as,
while(num!=-1){
cout<<"\n Enter a survey response from 1 to 10 (-1 to end): ";
cin>>num;
if(num<1 || num>10){
cout<<"\n Please enter a valid response from (1-10) ";
}
else{
outFile << num <<" ";
}
}
Next, for your void readRecordsFromFile() function, if your ultimate goal is only to count the number of appearances of the numbers entered, then you could use a 10 element counter array. and while reading from the file any digit you got, you just increase the element at the particular index of the counter array. say, you read 3 from the file, so you will just increase counter[3] as counter[3]++ to count the appearance of 3 in the file. Think about it.
while(/*end of file condition*/){
int a;
inFile>>a;
counter[a]++;
}
Hope it helped...
Well, the good news is you have tons of options to fix your issues. Here are some suggestions:
In order to avoid having the '-1' in the .txt file, I might change your loop to look like this:
while(num!=-1){
cout<<"\n Enter a survey response from 1 to 10 (-1 to end): ";
cin>>num;
if (num == -1) break; // will break out of loop before adding num!
if (num>0 && num<=10) outFile << num <<" "; // add only a valid number
// Note: if number is not 1 thru 10 or -1, loop simply repeats!
}
As for your second function, you have a variety of options, but I would suggest using a vector to contain the numbers. To use vectors, you need the library:
#include <vector>
Vectors are dynamic arrays -- you can add or delete elements to them as you wish. Your function might look like this:
void readRecordsFromFile(){
ifstream inFile("numbers.txt",ios::in);
if(!inFile){
cerr<<"File was not found";
exit (1);
}
vector <int> vNums; // a container for your int values
int inNum; // hold int for loading into vector
// Read each number to inNum, then add it to the vector
while (!inFile.eof()) {
inFile >> inNum; // load your input
vNums.push_back(inNum); // "push_back" adds an element
}
// Output the numbers... you may want to use a vector iterator for this
int x = 0;
while (x < vNums.size() ) {
cout << x+1 << " - " << vNums[x] << "\n";
x++;
}
}
Another option would be to use dynamic memory (new / delete), with linked lists. Here's a tutorial:
http://www.cprogramming.com/tutorial/lesson15.html
I think using a vector is a better solution, though! Best of luck.
return static_cast<double>(numerator/denominator);
Probably you prefer to cast each variable to double first and divide later. This is the difference:
If int: 2/4 == 0, so that static_cast<double>(numerator/denominator) returns 0.
If double (or float): 2./4. == 0.5, so that static_cast<double>(numerator) / static_cast<double>(denominator) returns 0.5.

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