after push_back cin doesnt work - c++

I have a problem with this code:
int main()
{
int x, sum = 0, how_many;
vector<int> v;
cout << "Write few numbers (write a letter if u want to end)\n";
while (cin >> x)
{
v.push_back(x);
}
cout << "How many of those first numbers do u want to sum up?" << endl;
cin >> how_many;
for (int i = 0; i < how_many; ++i)
{
sum += v[i];
}
cout << "The sum of them is " << sum;
return 0;
}
The problem is that console doesn't let me even write sth into how_many and error occurs. When I put lines 6 and 7 before cout << "Write few..." it all works perfectly. Can someone tell me why is that happening?

The loop ends when cin fails to convert the input into an integer, which leaves cin in a bad state. It also still contains final line of input. Any further input will fail, unless you clear the bad state:
cin.clear(); // clear the error state
cin.ignore(-1); // ignore any input still in the stream
(If you like verbosity, you could specify std::numeric_limits<std::stream_size>::max(), rather than relying on the conversion of -1 to the maximum value of an unsigned type).

You need to clear the cin error state because you ended the int vector read operation by an error.
cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

Related

Why doesn't std::cin.clear() work in this simple program?

I was solving some exercises to pass the time, and I encountered a behaviour I didn't understand, I am going to explain:
The exercise:
Write a program that reads and stores a series of integers and then computes the sum of the first N integers. First, ask for N, then read the values into a vector, then calculate the sum of the first N values.
Since I asked for N as the second step:
In the second std::cin (std::cin >> values_to_compute) it has to leave the while statement to continue the program, "only possible if" what is read is not a double. So I can type, for example; 'k' or "how are you?" or Ctrl + Z (I am on Windows 10).
int main() {
try {
double holder {0};
std::vector<double> values;
while (std::cin >> holder) {
values.push_back(holder);
}
std::cin.clear();
std::cout << "Out of the loop, now entering to the other std::cin\n";
int values_to_compute {0};
std::cin >> values_to_compute;
std::cout << "Computing...\n";
double result_computed {0};
for (int i {0}; i < values_to_compute; ++i) {
result_computed += values[i];
}
std::cout << "Result computed " << result_computed << '\n';
system("pause");
return 0;
}
catch (std::runtime_error& e) {
std::cerr << e.what() << '\n';
system("pause");
return 1;
}
}
Ok so?
So... std::cin leaves the while in a not good() state. I have to call std::cin.clear() to be able to use std::cin again.
Ok, and?
Well, if I type Ctrl+Z to exit the while loop, the std::cin.clear() works; if I type something that is not Ctrl + Z the std::cin.clear() doesn't work.
I want to know the why of that behaviour.
That's because std::cin::clear clears the error state of cin but it does not remove the data from the stream. You can use std::cin::ignore() to read and discard a line of text before reading values_to_compute.
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Make sure to #include <limits> to get std::numeric_limits.

Infinite loop when using exceptions in c++11

I would like to create a c++11 program that takes in 10 positive integers and gives the user the total. In the event of a negative number or a char input, the exception should be thrown and the user must re enter their value.
The program below works with negative numbers. However, when I enter a character like "a", the program goes into an infinite loop and I cannot figure out why.
Any and all help will be appreciated
#include <iostream>
int main(){
int array[10] = {0};
int total = 0;
for(int i =0; i < 10; i++){
std::cout<<"Number "<< i+1 << ": " <<std::endl;
std::cin >> array[i];
try{
if(array[i] < 0 || std::cin.fail())
throw(array[i]);
}
catch(int a){
std::cout<< a <<" is not a positive number! "<<std::endl;
i-=1; // to go back to the previous position in array
}
}
for(int k = 0; k < 10; k++)
total+=array[k];
std::cout<<"Total: " <<total<<std::endl;
}
If you get invalid input there are two things to thing you need to do:
Clear the stream status. This is done using the clear function.
Remove the invalid input from the buffer. This is usually done using the ignore function.
As for your program, you don't need exceptions here, just using unsigned integers and checking the status is enough:
unsigned int array[10] = { 0 };
...
if (!(std::cin >> array[i])
{
std::cout << "Please input only non-negative integers.\n";
// First clear the stream status
std::cin.clear();
// Then skip the bad input
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// Make sure the index isn't increased
--i;
}
To use exceptions similar to what you do now, the solution is almost exactly the same as above:
unsigned int array[10] = { 0 };
...
if (!(std::cin >> array[i])
{
throw i;
}
catch (int current_index)
{
std::cout << "The input for number " << current_index + 1 << " was incorrect.\n";
std::cout << "Please input only non-negative integers.\n";
// First clear the stream status
std::cin.clear();
// Then skip the bad input
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// Make sure the index isn't increased
--i;
}
Do not forget to include limits header file while using following line in your code :
std::cin.ignore(std::numeric_limits::max(), '\n');
because numeric_limits template is defined in this header file !

Stack around the variable is corrupted

I have what seems like a pretty simple, beginner question that I must be missing something obvious. I am just trying to prompt the user to input a 4 digit number and then take in the input as an array, splitting up the digits to be by themselves. I thought it hade something to do with "cin >> input[4]" I just can't seem to get the right answer.
int main()
{
int input[4]; //number entered by user
cout << "Please enter a combination to try for, or 0 for a random value: " << endl;
cin >> input[4];
}
When I go to run it, I get an error message "Stack around the variable was corrupted.
I tried looking at similar examples in other questions but I just can't seem to get it right. I need the input as one 4 digit number and then split it up to a 4 position array.
If anyone could help I would greatly appreciate it.
Your array is of size 4, so elements have indicies 0 .. 3; input[4] is located behind the end of your array so you are attemping to modify memory not allocated or allocated for other stuff.
This will work for you:
cin >> input[0];
cin >> input[1];
cin >> input[2];
cin >> input[3];
You do not need an arry to input 4 digit number.
int in;
int input[4];
cin >> in;
if(in>9999 || in < 1000) {
out << "specify 4 digit number" << endl;
return;
}
input[0] = in%1000;
input[1] = (in-1000*input[0])%100;
input[2] = (in-1000*input[0]-100*input[1])%10;
input[3] = in-1000*input[0]-100*input[1]-input[2]*10;
The problem is that you are trying to read in a character that does not exist (the one at index 4).If you declare input as int input[4];, then it doesn't have any characters at index 4; only indices 0...3 are valid.
Perhaps you should just use an std::string and std::getline(), and you could then parse the user input to integers however you like. Or you can try
std::cin >> input[0] >> input[1] >> input[2] >> input[3];
if you can live with the constraint that the numbers must be whitespace-separated.
This includes a small bit of error checking:
int n = 0;
while( n < 1000 || n >= 10000 ) // check read integer fits desired criteria
{
cout << "enter 4 digit number: ";
cin >> n; // read the input as one integer (likely 10 digit support)
if( !cin.good() ) // check for problems reading the int
cin.clear(); // fix cin to make it useable again
while(cin.get() != '\n'); // make sure entire entered line is read
}
int arr[4]; // holder for desired "broken up" integer
for( int i=0, place=1; i<4; ++i, place *= 10 )
arr[i] = (n / place) % 10; // get n's place for each slot in array.
cout << arr[3] << " " << arr[2] << " " << arr[1] << " " << arr[0] << endl;

do while loops can't have two cin statements?

I'm just following a simple c++ tutorial on do/while loops and i seem to have copied exactly what was written in the tutorial but i'm not yielding the same results. This is my code:
int main()
{
int c=0;
int i=0;
int str;
do
{
cout << "Enter a num: \n";
cin >> i;
c = c + i;
cout << "Do you wan't to enter another num? y/n: \n";
cin >> str;
} while (c < 15);
cout << "The sum of the numbers are: " << c << endl;
system("pause");
return (0);
}
Right now, after 1 iteration, the loop just runs without asking for my inputs again and only calculating the sum with my first initial input for i.
However if i remove the second pair of cout/cin statements, the program works fine..
can someone spot my error please? thank you!
After you read the string with your cin >> str;, there's still a new-line sitting in the input buffer. When you execute cin >> i; in the next iteration, it reads the newline as if you just pressed enter without entering a number, so it doesn't wait for you to enter anything.
The usual cure is to put something like cin.ignore(100, '\n'); after you read the string. The 100 is more or less arbitrary -- it just limits the number of characters it'll skip.
If you change
int str;
to
char str;
Your loop works as you seem to intend (tested in Visual Studio 2010).
Although, you should also probably check for str == 'n', since they told you that they were done.
...and only calculating the sum with my first initial input for i...
This is an expected behavior, because you are just reading the str and not using it. If you enter i >= 15 then loop must break, otherwise continues.
I think you wanted this thing
In this case total sum c will be less than 15 and continue to sum if user inputs y.
#include<iostream>
using namespace std;
int main()
{
int c=0;
int i=0;
char str;
do
{
cout << "Enter a num: \n";
cin >> i;
c = c + i;
cout << "Do you wan't to enter another num? y/n: \n";
cin >> str;
} while (c < 15 && str=='y');
cout << "The sum of the numbers are: " << c << endl;
return 0;
}

How do I make a C++ program that filter out non-integers?

Something like this
cout << "Enter the number of columns: " ;
cin >> input ;
while( input != int ){
cout << endl <<"Column size must be an integer"<< endl << endl;
cout << "Enter the number of columns: " ;
cin >> input ;
}
cin will do this for you, kind of. cin will fail if it receives something that is not of the same type as input. What you can do is this:
int input;
while(!(cin >> input))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << endl <<"Column size must be an integer"<< endl << endl;
cout << "Enter the number of columns: " ;
}
The cin.clear() clears the error bits, and cin.ignore() clears the input stream. I'm using number_limits to get the maximum size of the stream, that requires that you #include<limits>. Alternatively you can just use a big number or a loop.
You can't do it like that; input has to have some concrete type.
The simplest approach that will work is to read a string from cin, then convert it to an integer in a second step with strtol or one of its relatives, and issue an error message if strtol doesn't consume the whole string.
#include<iostream.h>
using namespace std;
int main()
{
int x;
int input;
while(!0){
cout<<"Enter your option :";
cout<<"1 .Enter Column size :"<<endl;
cout<<"2.Exit "<<endl;
cin>>x;
switch(x)
{
case 1: cout << "Enter the number of columns: "<<endl ;
cin>>input;
if(input>0)
cout << "The number of columns: is "<<input<<endl ;
else
cout << "Enter the number of columns as integer "<<endl ;
case 2:exit(0);
}
};
return 0;
}
Many of the answers here use the cin's built in filter. While these work to prevent a char or string from being entered, they do not prevent a float entry. When a float is entered, it is accepted and the decimal value remains in the buffer. This creates problems with later requests to cin. The following code will check the cin error flag and also prevent float inputs.
*note: The cin.ignore statement may require some tweaking to fully bullet proof the code.
void main()
{
int myint;
cout<<"Enter an integer: ";
intInput(myint);
}
void intInput(int &x)
{
bool valid = true; //flag used to exit loop
do
{
cin>>x;
//This 'if' looks for either of the following conditions:
//cin.fail() returned 'true' because a char was entered.
//or
//cin.get()!='\n' indicating a float was entered.
if(cin.fail() || cin.get()!='\n')
{
cout<<"Error. The value you entered was not an integer."<<endl;
cout<<"Please enter an integer: ";
cin.clear(); //clears cin.fail flag
cin.ignore(256,'\n'); //clears cin buffer
valid = false; //sets flag to repeat loop
}
else valid = true; //sets flag to exit loop
}while(valid == false);
}
This is a very basic solution to your problem that newer programers should find useful for people trying to break their programs. Eventually there are more advanced and efficient ways to do this.
int input;
int count = 1;
while(count == 1){ //this is just a simple looping design
cin >> input;
if(cin.fail()){ //If the input is about to crash your precious program
cin.clear(); //Removes the error message from internal 'fail safe'
cin.ignore(std::numeric_limits<int>::max(), '\n'); //Removes the bad values creating the error in the first place
count = 1; //If there is an error then it refreshes the input function
}
else{
count--; //If there is no error, then your program can continue as normal
}
}
Here is the advanced code: stackoverflow.com/questions/2256527/