Count the occurrence of numbers in C++? - 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;
}
}

Related

C++ code - Error message when floating point is entered [duplicate]

I've written a program that returns the median value of a user-defined array. While I've put a few checks in my code (array size can not be negative) I keep running into one issue I simply can not fix (for clarity sake, assume strings and alphabetical characters will not be used).
All of my input values are int however the user could just as easily enter in a float. When they do this (either for size of array or entering in the element) it breaks my code. I've tried multiple things to try and catch this, but it seems like the way my program is getting the value doesn't allow for the catch in time.
#include <iostream>
using namespace std;
void sort(int * a,int n)
{
for(int i=0;i<n;++i)
for(int j=i+1;j<n;++j)
{
if(a[i]>a[j])
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}\
}
return;
}
int main()
{
int n;
int check;
int x;
cout<<"Enter length of array:";
cin>>n;
if (n < 0){
while (n < 0){
cout << "Please enter a length greater than 0" << endl;
cin >> n;
}
} else if (n % 1 != 0){
while (n % 1 != 0){
cout << "Whole numbers only! Try again" << endl;
cin >> n;
}
}
if (n == 0){
cout <<"You try to enter numbers, but there's no place to put them." << endl;
cout << ":(";
return 0;
}
int a[n];
cout<<"Enter values one by one:\n";
for(int i=0;i<n;++i){
cin >> x;
a[i] = int(x);
}
sort(a,n);
if (n % 2 == 1){
cout<<"Median is:"<<a[n/2]<<endl;
}
else{
float z = (float(a[n/2]) + float(a[(n/2)-1])) / 2;
cout << "Median is:" << z << endl;
}
return 0;
}
First thing I tried was catching the float like so
`if (n % 1 !=0){
while(n % 1 !=0){
cout << "Enter a whole number"
cin >> n
}
}`
This still broke my program. The odd thing was that I entered a float and then printed the value of n and it only showed the int value.
I tried using typeid.n() with #include <typeinfo>and comparing that to an int type to check it was the correct value, but that slipped through as well.
I tried doing an int cast, something like int(n) immediately after number was stored in n but before it went into a[n] and yet again, it still broke my code.
How can I check against float user-input and loop them until they give me an int?
You're reading into an int:
int x;
...
cin >> x;
So it will read what it can, then stop at e.g. a . and leave the rest on the stream (like if the user enters "123.4" you'll get 123 and then ".4" won't be consumed from the input stream).
Instead, you could read into a float:
float x;
...
cin >> x;
And do the appropriate math.
Alternatively you could read into a string and parse it into a float. That way you won't get stuck at letters and such either.
And the final option is to read into an int but handle any errors and skip the bad input, which is detailed at How to handle wrong data type input so I won't reproduce it here.
Which option you choose really just depends on what you want the behavior of your program to be and how strictly you want to validate input (e.g. round vs. fail if "2.5" is entered but an integer is expected, how do you want to handle "xyz" as input, etc.).

Floats breaking my code

I've written a program that returns the median value of a user-defined array. While I've put a few checks in my code (array size can not be negative) I keep running into one issue I simply can not fix (for clarity sake, assume strings and alphabetical characters will not be used).
All of my input values are int however the user could just as easily enter in a float. When they do this (either for size of array or entering in the element) it breaks my code. I've tried multiple things to try and catch this, but it seems like the way my program is getting the value doesn't allow for the catch in time.
#include <iostream>
using namespace std;
void sort(int * a,int n)
{
for(int i=0;i<n;++i)
for(int j=i+1;j<n;++j)
{
if(a[i]>a[j])
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}\
}
return;
}
int main()
{
int n;
int check;
int x;
cout<<"Enter length of array:";
cin>>n;
if (n < 0){
while (n < 0){
cout << "Please enter a length greater than 0" << endl;
cin >> n;
}
} else if (n % 1 != 0){
while (n % 1 != 0){
cout << "Whole numbers only! Try again" << endl;
cin >> n;
}
}
if (n == 0){
cout <<"You try to enter numbers, but there's no place to put them." << endl;
cout << ":(";
return 0;
}
int a[n];
cout<<"Enter values one by one:\n";
for(int i=0;i<n;++i){
cin >> x;
a[i] = int(x);
}
sort(a,n);
if (n % 2 == 1){
cout<<"Median is:"<<a[n/2]<<endl;
}
else{
float z = (float(a[n/2]) + float(a[(n/2)-1])) / 2;
cout << "Median is:" << z << endl;
}
return 0;
}
First thing I tried was catching the float like so
`if (n % 1 !=0){
while(n % 1 !=0){
cout << "Enter a whole number"
cin >> n
}
}`
This still broke my program. The odd thing was that I entered a float and then printed the value of n and it only showed the int value.
I tried using typeid.n() with #include <typeinfo>and comparing that to an int type to check it was the correct value, but that slipped through as well.
I tried doing an int cast, something like int(n) immediately after number was stored in n but before it went into a[n] and yet again, it still broke my code.
How can I check against float user-input and loop them until they give me an int?
You're reading into an int:
int x;
...
cin >> x;
So it will read what it can, then stop at e.g. a . and leave the rest on the stream (like if the user enters "123.4" you'll get 123 and then ".4" won't be consumed from the input stream).
Instead, you could read into a float:
float x;
...
cin >> x;
And do the appropriate math.
Alternatively you could read into a string and parse it into a float. That way you won't get stuck at letters and such either.
And the final option is to read into an int but handle any errors and skip the bad input, which is detailed at How to handle wrong data type input so I won't reproduce it here.
Which option you choose really just depends on what you want the behavior of your program to be and how strictly you want to validate input (e.g. round vs. fail if "2.5" is entered but an integer is expected, how do you want to handle "xyz" as input, etc.).

jumping outside loop in a specific case

I am writing a code that, for one or several lines of strings, find if the overall input has only "cool" (it's first middle and last string are the same) lines, only "uncool" lines or a mix of both.
The problem I'm having is whenever I input an even number the while loop terminates. Debugging I found that, just before jumping out n gets value 0 but I don't understand how this would make the loop end.
This is the code:
#include <iostream>
using namespace std;
int main () {
// Bool has control if we have found a cool line/non-cool line
bool cool = false;
bool uncool = false;
int n; //lenght of input
while (cin >> n) {
if (cool and uncool) break; // we have found one of each so we know it is a mixed input
else if (n%2 == 0) uncool = true; // if the lenght is even there is no middle string
else {
// we are trying to see if the middle and last string are equal to the first
string comparing_string;
cin >> comparing_string;
string rest_of_sequence;
bool this_is_cool = true;
for (int i = n-2; i >= 0; i--) { // we input the rest of strings and compare them to the first
cin >> rest_of_sequence;
if ((i == n/2 or i == 0) and rest_of_sequence != comparing_string) this_is_cool = false;
}
if (this_is_cool) cool = true;
else uncool = true;
}
}
if (cool and uncool) cout << "both types" << endl;
else if (cool and not uncool) cout << "all cool" << endl;
else if (uncool and not cool) cout << "none cool" << endl;
}
Any help is appreciated! I'm currently in first year of uni and always open to recommended books/webpages/videos to continue learning :)
The problem was that I thought the program would just ignore input that wasn't an integer in the while loop, but it doesn't.
Now the code is correct:
else if (n%2 == 0) {// if the lenght is even there is no middle string
uncool = true;
string just_passing_input;
for (int i = n; i > 0; i--) cin >> just_passing_input;
}
Thanks for the helpful feedback, I shall now continue learning.

How would I get this to repeat without getting stuck on invalid input?

quick question.
How would I get this code to loop itself so that it keeps asking the question, but still allow a different action when a non-numeric input is given?
int main()
{
int temp = 0;
while (temp =1, 10)
{
int amend_numb = -1;
cout << "\nWhich amendment? ";
cin >> amend_numb;
if (amend_numb == 1)
{
cout << "a.\n";
}
if (amend_numb == 2)
{
cout << "b.\n";
}
I attempted to put it into this while statement, however if I enter anything other than an integer into the cin, then it does an infinite loop of constantly repeating the cout statement. Is there any way to get rid of this problem?
while (temp =1, 10)
Although the expression is syntactically correct, it may not perform the way you think:
1. Assign temp to 1.
2. Disregard the value returned from the assignment (because of comma operator)
3. Remaining expression is 10, which is nonzero, so loop continues.
The general rule of thumb is to use a for loop for known quantities of iterations:
for (temp = 1; // assignment
temp < 10; // continuation expression
++temp) // iterator incrementing
{
// loop content
}
When interacting with Users, you want the loop to repeat until an exit condition is satisfied.
unsigned int temp = 0;
while (temp != 0)
{
cout << "Enter amendment number, 0 to quit: ";
cin >> temp;
if (temp > 0)
{
switch (temp)
{
//...
}
}
}
Some people like a forever loop with a break statement:
unsigned int temp = 0;
while (true)
{
cout << "Enter amendment number, 0 to quit: ";
cin >> temp;
if (temp == 0)
{
break; // terminate loop
}
switch(temp)
{
//...
}
}
while (true)
{
//your code
}
simple
and then for your none integer input, you should really do a type cast if you think the user might not provide expected input. Since cin would return a string so you should use string to int cast, something like "stoi" if your compiler supports it or look up c++ string to int I am pretty sure you will get bunch answers.
Edit: if the user might enter anything that is not a number, then you better check for error, put a try and catch statement between the cast, if it fails then tell the user input is not valid.

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.