This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 3 years ago.
I have a C++ program. I want to get a number from the user (t) and force the user to enter line t times but the program's execution terminates after 1 iteration. This is the code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
int t;
cin >> t;
for (int i=0; i< t; i++) {
getline(cin, str);
cout << str;
}
return 0;
}
Can anyone explain me why this happening and how to solve it?
Thank you my friends.
The newline character is still in the buffer when you do cin >> t so the next line you read will be blank. When you mix formatted input (>>) and unformatted (std::getline) you often get in situations like this and you need to take measures when switching to unformatted input. Example remedy:
#include <iostream>
#include <limits>
#include <string>
using namespace std;
int main() {
string str;
int t;
cin >> t;
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // skip the rest of the line
for(int i = 0; i < t; i++) {
if(getline(cin, str)) // check that the getline actually succeeded
cout << str << '\n';
else
break;
}
return 0;
}
When you enter your first character (the times to repeat), a character is left in the cin buffer - newlines are not consumed by cin >>. As a result, getline(cin, str) reads this character and takes it as the first input, which then empties the buffer out and lets you enter the others.
You can clear the buffer with std::cin.ignore(1); to remove that trailing character - this lets your code run as anticipated. Why not just use cin >> str, though? That solves the problem and avoids a call to getline.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
int t;
cin >> t;
//clear one character out of buffer
cin.ignore(1);
//note that 1 is used for demonstration purposes
//in development code, INT_MAX, numeric_limits<streamsize>::max(),
//or some other large number would be best, followed
//by std::cin.clear()
for (int i=0; i< t; i++) {
cout << "input: ";
//you could use cin >> str; instead of getline(cin, str);
getline(cin, str);
cout << "got: " << str << std::endl;
}
return 0;
}
Demo
Hello everyone this problem made me crazy
i have to take large line as input T number of times. I use following code
#include <iostream>
#include <string.h>
using namespace std;
int main() {
int T;
char buffer,b1;
cin >> T>> b1;
//fflush(stdin);
while(T--)
{
char ch,c;
int A[14];
while((ch=getchar())!='\n')
{
cout << ch;
}
}
return 0;
}
I know if we taken input character after integer then it store null as a character thats why i take an extra input as b1(as a buffer) so that null will store in it.
when i pass input as
2
758
8758
It gives following output
58
8758
As BLUPIXY suggested in comments replace
cin >> T>> b1;
with
cin >> T; cin.ignore();
It works
I'm writing a program that prompts the user for:
Size of array
Values to be put into the array
First part is fine, I create a dynamically allocated array (required) and make it the size the user wants.
I'm stuck on the next part. The user is expected to enter in a series of ints separated by commas such as: 1,2,3,4,5
How do I take in those ints and put them into my dynamically allocated array? I read that by default cin takes in integers separated by whitespace, can I change this to commas?
Please explain in the simplest manner possible, I am a beginner to programming (sorry!)
EDIT: TY so much for all the answers. Problem is we haven't covered vectors...is there a method only using the dynamically allocated array I have?
so far my function looks like this. I made a default array in main. I plan to pass it to this function, make the new array, fill it, and update the pointer to point to the new array.
int *fill (int *&array, int *limit) {
cout << "What is the desired array size?: ";
while ( !(cin >> *limit) || *limit < 0 ) {
cout << " Invalid entry. Please enter a positive integer: ";
cin.clear();
cin.ignore (1000, 10);
}
int *newarr;
newarr = new int[*limit]
//I'm stuck here
}
All of the existing answers are excellent, but all are specific to your particular task. Ergo, I wrote a general touch of code that allows input of comma separated values in a standard way:
template<class T, char sep=','>
struct comma_sep { //type used for temporary input
T t; //where data is temporarily read to
operator const T&() const {return t;} //acts like an int in most cases
};
template<class T, char sep>
std::istream& operator>>(std::istream& in, comma_sep<T,sep>& t)
{
if (!(in >> t.t)) //if we failed to read the int
return in; //return failure state
if (in.peek()==sep) //if next character is a comma
in.ignore(); //extract it from the stream and we're done
else //if the next character is anything else
in.clear(); //clear the EOF state, read was successful
return in; //return
}
Sample usage http://coliru.stacked-crooked.com/a/a345232cd5381bd2:
typedef std::istream_iterator<comma_sep<int>> istrit; //iterators from the stream
std::vector<int> vec{istrit(in), istrit()}; //construct the vector from two iterators
Since you're a beginner, this code might be too much for you now, but I figured I'd post this for completeness.
A priori, you should want to check that the comma is there, and
declare an error if it's not. For this reason, I'd handle the
first number separately:
std::vector<int> dest;
int value;
std::cin >> value;
if ( std::cin ) {
dest.push_back( value );
char separator;
while ( std::cin >> separator >> value && separator == ',' ) {
dest.push_back( value );
}
}
if ( !std::cin.eof() ) {
std::cerr << "format error in input" << std::endl;
}
Note that you don't have to ask for the size first. The array
(std::vector) will automatically extend itself as much as
needed, provided the memory is available.
Finally: in a real life example, you'd probably want to read
line by line, in order to output a line number in case of
a format error, and to recover from such an error and continue.
This is a bit more complicated, especially if you want to be
able to accept the separator before or after the newline
character.
You can use getline() method as below:
#include <vector>
#include <string>
#include <sstream>
int main()
{
std::string input_str;
std::vector<int> vect;
std::getline( std::cin, input_str );
std::stringstream ss(str);
int i;
while (ss >> i)
{
vect.push_back(i);
if (ss.peek() == ',')
ss.ignore();
}
}
The code is taken and processed from this answer.
Victor's answer works but does more than is necessary. You can just directly call ignore() on cin to skip the commas in the input stream.
What this code does is read in an integer for the size of the input array, reserve space in a vector of ints for that number of elements, then loop up to the number of elements specified alternately reading an integer from standard input and skipping separating commas (the call to cin.ignore()). Once it has read the requested number of elements, it prints them out and exits.
#include <iostream>
#include <iterator>
#include <limits>
#include <vector>
using namespace std;
int main() {
vector<int> vals;
int i;
cin >> i;
vals.reserve(i);
for (size_t j = 0; j != vals.capacity(); ++j) {
cin >> i;
vals.push_back(i);
cin.ignore(numeric_limits<streamsize>::max(), ',');
}
copy(begin(vals), end(vals), ostream_iterator<int>(cout, ", "));
cout << endl;
}
#include <iostream>
using namespace std;
int main() {
int x,i=0;
char y; //to store commas
int arr[50];
while(!cin.eof()){
cin>>x>>y;
arr[i]=x;
i++;
}
for(int j=0;j<i;j++)
cout<<arr[j]; //array contains only the integer part
return 0;
}
The code can be simplified a bit with new std::stoi function in C+11. It takes care of spaces in the input when converting and throws an exception only when a particular token has started with non-numeric character. This code will thus accept input
" 12de, 32, 34 45, 45 , 23xp,"
easily but reject
" de12, 32, 34 45, 45 , 23xp,"
One problem is still there as you can see that in first case it will display " 12, 32, 34, 45, 23, " at the end where it has truncated "34 45" to 34. A special case may be added to handle this as error or ignore white space in the middle of token.
wchar_t in;
std::wstring seq;
std::vector<int> input;
std::wcout << L"Enter values : ";
while (std::wcin >> std::noskipws >> in)
{
if (L'\n' == in || (L',' == in))
{
if (!seq.empty()){
try{
input.push_back(std::stoi(seq));
}catch (std::exception e){
std::wcout << L"Bad input" << std::endl;
}
seq.clear();
}
if (L'\n' == in) break;
else continue;
}
seq.push_back(in);
}
std::wcout << L"Values entered : ";
std::copy(begin(input), end(input), std::ostream_iterator<int, wchar_t>(std::wcout, L", "));
std::cout << std::endl;
#include<bits/stdc++.h>
using namespace std;
int a[1000];
int main(){
string s;
cin>>s;
int i=0;
istringstream d(s);
string b;
while(getline(d,b,',')){
a[i]= stoi(b);
i++;
}
for(int j=0;j<i;j++){
cout<<a[j]<<" ";
}
}
This code works nicely for C++ 11 onwards, its simple and i have used stringstreams and the getline and stoi functions
You can use scanf instead of cin and put comma beside data type symbol
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a[10],sum=0;
cout<<"enter five numbers";
for(int i=0;i<3;i++){
scanf("%d,",&a[i]);
sum=sum+a[i];
}
cout<<sum;
}
First, take the input as a string, then parse the string and store it in a vector, you will get your integers.
vector<int> v;
string str;
cin >> str;
stringstream ss(str);
for(int i;ss>>i;){
v.push_back(i);
if(ss.peek() == ','){
ss.ignore();
}
}
for(auto &i:v){
cout << i << " ";
}
I have an input file that contains some data in coordinate mode
For example (2,3,5) translates to column 2, row 3, and level 5. I'm curious on a method of reading in the numbers after using getline(cin,string) to obtain the data. I don't know how many digits are in the data points so i can't assume the 1st character will be of length 1. Is there any libraries that can help solve the problem faster?
my gameplan so far that's not finished
void findNum(string *s){
int i;
int beginning =0;
bool foundBegin=0;
int end=0;
bool foundEnd=0
while(*s){
if(isNum(s)){//function that returns true if its a digit
if(!foundBegin){
foundBegin=1;
beginning=i;
}
}
if(foundBegin==1){
end=i;
foundBegin=0;
}
i++;
}
}
Try this:
#include <iostream>
#include <cstdlib>
#include <sstream>
#include <vector>
#include <string>
int main() {
std::vector <std::string> params;
std::string str;
std::cout << "Enter the parameter string: " << std::endl;
std::getline(cin, str);//use getline instead of cin here because you want to capture all the input which may or may not be whitespace delimited.
std::istringstream iss(str);
std::string temp;
while (std::getline(iss, temp, ',')) {
params.push_back(temp);
}
for (std::vector<std::string>::const_iterator it=params.begin(); it != params.end(); ++it) {
std::cout << *it << std::endl;
}
return 0;
}
The only caveat is that the arguments will have to be non whitespace delimited.
Example input string:
1,2,3
Output:
1
2
3
Once these arguments have been parsed, you can then convert them from strings to (example) integer via the following:
template <typename T>
T convertToType(const std::string &stringType) {
std::stringstream iss(stringType);
T rtn;
return iss >> rtn ? rtn : 0;
}
which can be used as follows:
int result = convertToType<int>("1");//which will assign result to a value of 1.
UPDATE:
This now works correctly on whitespace delimited input (except for newlines) like the following:
1 , 2, 3 , 4
Which yields:
1
2
3
4
jrd1's answer is pretty good, but if you'd prefer there happen to be functions for converting characters to integers (and back) already in the C standard library (cstdlib). You'd be looking for atoi.
http://en.cppreference.com/w/cpp/string/byte/atoi
#include <sstream>
void findNums(const string &str, int &i, int &j, int &k)
{
std::stringstream ss(str);
char c;
ss >> c >> i >> c >> j >> c >> k;
}
Simply use extractor operator for reading any type of value in respective variable type.
#incude<ifstream> // for reading from file
#include<iostream>
using namespace std;
int main()
{
int number;
ifstream fin ("YouFileName", std::ifstream::in);
fin >> number; // put next INT no matter how much digit it have in number
while(!fin.eof())
{
cout << number << endl;
fin >> number; // put next INT no matter how much digit it have in number and it will ignore all non-numeric characters between two numbers as well.
}
fin.close();
return 0;
}
Have a look over here for more details.
Note: Be careful while using it for character arrays and strings.. :)
I tried to write a code that asked me to input numbers one by one and when a certain char was inserted ( in this case 'x' ) it would stop the loop. But when I insert that char it starts spamming me with "Insert Number" . I think that the fault is that I'm trying to insert a char in an int array, but I can't think a way around it.
long int numbers[100]={0};
char h='y';
int index=0;
do
{
cout << "Insert Number : ";
cin >> numbers[index];
h=(char)numbers[index];
index++;
}
while(h!='x');
This happens because 'x' is not a number and cin >> numbers[index]; operation fails, without consuming that data. So the loop continues, gets the same x, fails again and everything starts all over again. You can check for result of input operation, something like this:
#include <iostream>
using namespace std;
int main ()
{
long int numbers[100]={0};
char h='y';
int index=0;
do
{
cout << "Insert Number : ";
if (cin >> numbers[index])
{
h=(char)numbers[index];
index++;
}
else
{
cout << "Hey, that was not a number! Bye." << endl;
break;
}
}
while(h!='x');
}
You should write a loop as:
while(cin >> numbers[index])
index++;
It will read all the integers, untill you enter some invalid input, be it 'x' or any other character. Now if you want to skip all invalid inputs and continue reading integers (which might be after invalid inputs), and want to consider only 'x' to exit from the loop, then wrap the above loop with another loop as:
char ch;
do
{
while(cin >> numbers[index])
index++;
cin.clear(); //clear the error flags, so you can use cin to continue reading
cin >> ch; //read the invalid character
} while(ch != 'x');
One piece of advice: prefer using std::vector<long int> over long int numbers[100]. What if user entered more than 100 integers, then your program will be corrupted.
Because you're trying to read in an integer, any character that isn't a digit can't be converted to a number and will jam up the input - you'll get an error and the bad character will not be removed from the stream. The next time you try to read you'll get the same error.
If you expect a number or a string, always read the input as a string, and try converting it to a number afterwards if the string isn't "x":
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
int main(int argc, char *argv[])
{
std::vector<long int> numbers;
std::string line;
while(std::getline(std::cin, line) && line != "x") {
std::istringstream input(line);
long int value;
// Check that there is only a number with nothing else after
if((input >> value) && input.get() == std::char_traits<char>::eof()) {
numbers.push_back(value);
} else {
std::cout << "Invalid Entry, please retry" << std::endl;
}
}
//...
return 0;
}