I have a simple structure which stores details of a person whose values needs to be initialized through user input. The structure is as follows :
typedef struct {
char name[20];
int age;
char address[50];
char vehicle[10];
}Runner;
I am using cin to store the value of each Runner but wish to take the inputs (that may contain whitespace in between) using enter key after each value entered.
Below is the code :
Runner run1;
cout << "Enter name age address vehicle (pressing enter at each instance)" << endl;
cin >> run1.name >> run1.age >> run1.address >> run1.vehicle ;
It is quite evident that space separated values would be considered as two unique entries.
How do I skip the white-spaces and cin only after enter is pressed. Also if there is another approach to such situations, it would be great to know the same.
As the input may have whitespaces between them, you should use getline function.
cin.getline(run1.name,20);
cin.getline(run1.address,50);
cin.getline(run1.vehicle,10);
cin >> age
But if you want to take the value of age after taking the value of name, then you'll have to do something like this.
cin.getline(run1.name,20);
cin >> run1.age;
cin.getline(dummy,5); //cin leaves a newline at the buffer. This line of code takes the newline from the buffer.
cin.getline(run1.address,50);
cin.getline(run1.vehicle,10);
cin.getline (name,20);
cin.getline (address,50);
cin.getline (vehicle,10);
cin >> age;
Related
I have declared a string array of [15]. Actually to store names. I execute it fine, but when I enter the complete name (including space; First name+[space]+last name) the program misbehaves. I cannot find the fault
I have declared multiple string arrays in the program, when I input the name with space it doesn't executes fine. I am using cin>> function to input in the array. like
string name[15];
int count=0; cout << "enter your name" << endl;
cin >> name[count];
I am using cin>> function to input in the array.
That is the problem. operator>> is meant for reading formatted input, so it stops reading when it encounters whitespace between tokens. But you want unformatted input instead. To read a string with spaces in it, use std::getline() instead:
string name[15];
int count=0;
cout << "enter your name" << endl;
getline(cin, name[count]);
Online Demo
When I enter a value for the group_input variable, the program finishes, and I can't enter a value for the fio_input variable. If I enter a short value, I can proceed to enter a value for the fio_input variable. What's the problem?
#include <iostream>
using namespace std;
int main()
{
unsigned char group_input, fio_input, result[7] = {0, 0, 0, 0, 0, 0, 0};
cout << "\n Enter your group name: ";
cin >> group_input;
cout << "\n Enter your full name: ";
cin >> fio_input;
}
You're asking for a name, which is an array of chars - a std::string.
#include <iostream>
#include <string>
int main(){
std::string group_input, fio_input;
std::cout << "\n Enter your group name: ";
std::cin >> group_input;
std::cout << "\n Enter your full name: ";
std::cin >> fio_input;
}
You shouldn't use use namespace std; read here why.
Also if you want to input names with spaces use std::getline(std::cin, str); instead. Because if you std::cin "Roger Jones" to fio_input it will only save "Roger"
When you read into a char variable, the system will read characters. And a single char can only store a single character, so that's what will be read.
If you give a multi-character input then the first character will be stored in group_input, and the second in fio_input.
If you want to read strings (which seems to be what you want) then use std::string.
Using std::string is especially important if you want to avoid buffer overflows. C++ doesn't have bound-checking of arrays.
In this line
cin >> group_input;
you read from the standard input and write the result to an unsigned char variable. How many bytes will be read? This depends on the overloaded operator >> invoked by the above line. In your case, both "input lines" invoke an overload for the unsigned char, as this data type can only store one byte, it reads one byte. Hence, you can either input one-character names for both variables, or you change the data type of group_input and fio_input to something else, e.g. std::string. In this case, the operator >> overload is invoked that reads anything up to the next whitespace (but not including it) byte, where "whitespace byte" includes tab, newline etc.
I have a database class that is an array that will hold a number of objects.
The function will take a couple of inputs from the user which include both strings and ints
For example:
std::cout << "Enter first name: ";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(std::cin, first_name);
std::cout << "Enter last name: ";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(std::cin, last_name);
std::cout << "Enter age: ";
std::cin >> age;
When I run the code, after I hit enter after entering the last name, it just starts a new line and I have to enter another input before it asks for the age input.
I heard it was bad to mix getline and cin, and that it's better to use one or the other. What can I do to make this work and what would be good practice moving forward?
Edit: I added in the ignores when I initially searched for solutions because without them, the code wouldn't bother waiting for user input. The output would be "Enter first name: Enter last name: "
Edit2: RESOLVED. Problem was I had used "cin >>" earlier in my code for user to input an int variable and needed the first cin.ignore statement, but not the other. Did not include that part of the code because I didn't know that was affecting it. Still new to all this so thanks everyone for their help!
Your std::cin::ignore calls are not helping you. They are only needed after an input that does not extract the end-of-line character (>>).
std::string first_name;
std::string last_name;
int age;
std::cout << "Enter first name: ";
std::getline(std::cin, first_name); // end of line is removed
std::cout << "Enter last name: ";
std::getline(std::cin, last_name); // end of line is removed
std::cout << "Enter age: ";
std::cin >> age; // doesn't remove end of line
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // this does
// input can proceed as normal
You only need the std::cin::ignore call after std::cin >> age; because that doesn't remove the end of line character whereas the std::getline calls do.
According to the documentation of std::basic_istream::ignore(), this function behaves as an Unformatted Input Function which mean it is going to block and wait for user input if there is nothing to skip in the buffer.
In your case both of your ignore statments are not neccessary since std::getline() will not leave the new line character in the buffer. So what is actually happening is:
std::cout << "Enter first name: ";
/*your first input is skipped by the next ignore line because its going to block until
input is provided since there is nothing to skip in the buffer*/
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
/* the next getline waits for input, reads a line from the buffer and also removes the
new line character from the buffer*/
std::getline(std::cin, first_name);
std::cout << "Enter last name: ";
/*your second input is skipped by the next ignore line because its going to block until
input is provided since there is nothing to skip in the buffer*/
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
/* the next getline waits for input and this is why it seems you need to provide
another input before it ask you to enter the age*/
std::getline(std::cin, last_name);
You need to remove the ignore statments to make this work. You may also want to read When and why do I need to use cin.ignore() in C++
I recommend removing the ignore function calls:
std::string name;
std::cout << "Enter name: ";
std::getline(cin, name);
unsigned int age;
std::cout << "Enter age: ";
std::cin >> age;
I have the following code:
int choice = 0;
char st1[N];
cout << "enter choice" <<endl;
cin >> choice;
cout << "enter sentence" << endl;
cin.get(st1, N-1);
when getting to cin.get line, no matter what the input is, it will read \0 char into st1[0]
and that's it.
I assume it has something to do with the latest cin ( into choice variable ).
How do i "clean" cin buffer before getting new input from the user? if that's possible.
thanks
You might use ignore to drop the newline from the buffer (e.g. drop X characters before the newline as delimiter). Extraction and ignore stop when the delimiter is extracted.
e.g.
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Also related: Why would we call cin.clear() and cin.ignore() after reading input?
You could always try using cin.sync().
Do a getchar() after cin >> choice;. This will consume the \n from the input buffer.
Since choice is of type int, the \n is left over in the buffer and when the string input is taken, this \n is encountered and it stops taking input there.
It seems that it's not separating the word within the space.
Trying to separate the words in between, and stored it in first and second.
cin >> name; //input name
stringstream file (name);
getline(file,first, ' '); //seperate the name with the first name and last name using space
getline(file,second, ' ');
Replace
cin >> name;
with
getline(cin, name); //input name
cin >> reads only upto the first space. You would have realized this if you done a cout << name; to check what's getting read - this is the first step of debugging.
When you read the initial input with cin >> name; that only reads up to the first white space character.
You then try to break that into two pieces at white space, which it doesn't contain.
Easy way:
cin >> first >> second;
Alternatively, if you start with std::getline(cin, name); instead of cin >> name;, then the rest should work correctly.