cin.ignore() is not working in program - c++

My program is suppose to output First Middle Last name and ignore the , that is in the input. But in my program the comma is still in my output so obviously I am missing something.
#include <iostream>
#include <string>
using namespace std;
char chr;
int main()
{
string last, first, middle;
cout<< "Enter in this format your Last name comma First name Middle name."<<endl; //Input full name in required format
cin>>last; //receiving the input Last name
cin>>first; //receiving the input First name
cin>>middle; //receiving the input Middle name
cout<<first<<" "<<middle<< " " <<last; //Displaying the inputed information in the format First Middle Last name
cin.ignore(','); //ignoring the , that is not neccesary for the new format
cin>>chr;
return 0;
}

The ignore function acts on the current input stream (e.g. cin), and it discards as many characters as indicated in the first argument, until it finds the delimiter given as the second argument (default as EOF).
So, the way you have it, cin.ignore(','); will ignore 44 characters until EOF, after you have printed the inputs given. This is almost certainly NOT what you wanted to do.
If you want to skip past a comma, then you will want to call cin.ignore(100, ','); between the input of the last name and the input of first name. That will skip to the next comma in the input (up to 100 characters).

Related

How to keep taking 2 integers as input until program encounters a single integer?

I was given a question where the input will be like:
10 8
4 9
6 12
5 4
3
1
Here I don't know the number of lines that contains 2 integers. Those sets of 2 integers will be taken into an array. But when the program encounters "3", it will start taking input in another array.
I have tried this with
while(cin>>a>>b){ //some porcess with a and b }
but it doesn't work because it recognizes 3 and 1 as another set of two integers. Please help me to solve this problem.
cin >> a >> b skips not only spaces, but any delimeter characters too ('\n', '\t', ' ').
Here you actually may want to read input line-by-line and then check if there are two integers or one. Consider use of std::getline for retrieving each line of text. Then you can use read string as std::istream (like in example in the link above) and read from it with counting, how many numbers you read totally.
So think about your problem. Essentially it is, read one line at a time, and if it contains two numbers do one thing, but if it contains one number do something else.
But the code you have written reads numbers not lines. That is where the problem is.
Instead write your code to read only line at a time, analyse that line to see if it contains one or two numbers (or something else) and then proceed from there.
What you need is the ability to read a line of text into a string, and then read from that string into your numbers. To do that you use an istringstream. Something like this
#include <iostream>
#include <sstream>
#include <string>
int a, b;
string s;
getline(cin, s); // read one line from standard input
istringstream line(s); // put that string to a stream we can read from
if (line >> a) // try and read the first number from the stream
{
// got the first number
if (line >> b) // try and read the second number from the stream
{
// got the second number
...
}
else
{
// only one number
...
}
}
else
{
// didn't get any numbers, some sort of error
...
}

Getting multiline sentence input in c++

I am trying to take multiple lines of string input (may contain spaces) in c++ using 2D char array but the loop gets terminated without taking any input for n=1 in the code:
When n=2, it takes only one input and when I try to print input[0], it prints blank. But for cout<
char input[100][100];
int n,i;
cout<<"Enter no of lines : ";
cin>>n;
cout<<"Enter "<<n<<" sentences : "<<endl;
for(i=0;i<n;i++)
cin.getline(input[i],100);
This is a common problem when mixing formatted and unformatted input. After a formatted input, the internal buffer is positioned before the first blank character and before the \n. The bullet proof way would be to always use getline and then scan the first line to extract the number of lines. But for such a simple case, it is enough to use a dummy getline after reading the number of line to skip the end of line:
char input[100][100];
int n,i;
cout<<"Enter no of lines : ";
cin>>n;
cin.getline(input[0], 100); // skip the end of line
cout<<"Enter "<<n<<" sentences : "<<endl;
for(i=0;i<n;i++)
cin.getline(input[i],100);
But:
you should always test cin after a read (what if the user types erroneously e instead of 4?)
you should avoid char arrays and always use string in C++ (simpler, cleaner, less error prone)
When you enter number of lines(say 4) you press 4 and then enter key. It is stored as 4\n in stdin that is standard input. When you read using cin.getline() you are reading \n. You will have to use cin.ignore to ignore existing buffer in stdin. However using >> operator is better since it handles newlines.
For multiline input you can input a third parameter to getline(): a delimiter specifying what indicates the end of your input.

How does cin works in a while loop when the inputs are given in a single line with white spaces?

Consider this small piece of code:
#include <iostream>
#include<stdio.h>
using namespace std;
int main() {
int a;
while(true){
cin>>a;
cout<<a;
}
return 0;
}
Input
1 2 3 5 7 23
Output
125723
How I thought it will run is:
First iteration
1. Reads the first input ie '1' and stops reading further, right after reading the whitespace.
2.Prints the value 1.
Second iteration
1. Again asks for new input
2. Print that in the second line
But that doesn't happen instead it reads the elements we gave after space
First iteration:
Peek at next character in the stream. It's a digit ('1'), so read it.
Peek at next character in the stream. It's not a digit (' '), so don't read it; store 1 in a and return from >>.
(Output 1.)
Second iteration:
Peek at next character in the stream. It's whitespace (' '), so read and ignore it.
Peek at next character in the stream. It's a digit ('2'), so read it.
Peek at next character in the stream. It's not a digit (' '), so don't read it; store 2 in a and return from >>.
(Output 2.)
And so on ...
The point is that >> does not care about lines. cin is one long input stream of characters (some of which may be '\n'). The only thing you can do is read more characters (and then maybe decide that you don't want to do anything with them).
cin is not necessarily connected to a keyboard. The program that started you gets to decide where cin reads from. It can be a file, a network socket, or interactive user input. In the latter case, reading from cin may block until the user types more input, but it will never cause input to just be dropped.
If you want a sane user interface, always read whole lines and process them afterwards:
std::string line;
while (std::getline(std::cin, line)) {
// do stuff with line
}

Taking input as array of words in c++

std::vector<std::string> words;
std::string word;
while (std::cin >> word)
words.push_back(word);
cout<<words[1];
i am using this to take input to create an array of words with whitespaces.but after ending of sentence using Enter, i am not getting any output.
i am using this to take input to create an array of words with whitespaces.but after ending of sentence using Enter, i am not getting any output.
That's because
while (std::cin >> word)
words.push_back(word);
does not stop when you press Enter
It stops when there is no more data in std::cin. You have to enter EOF to get out of the while loop.
Useful link: How do i enter an EOF character in this program?.
using
getline(cin,word)
instead of
cin<<word
will allow you to input words with whitespaces.
Even, vector starts at index 0, hence output
words[0]
instead of
words[1]
will output the entered value. that is the problem.

Reading multiple items in data file C++

I'm a C++ beginner. I'm trying to read a file that is formatted like so:
5 Christine Kim # 30.00 3 1
15 Ray Allrich # 10.25 0 0
...
number string # number number number
where each number has its own significance and the name does as well. I can get the file open and read the first two items but after the name I can't get the numbers after. This is my function right now:
void getItems( ifstream& dataFile, // in file
Employee item[], // class array so I can store the data later
int &transNum) // number of transactions
{
int id; // employee ID
char name[20]; // employee name
double hourlyPay; // pay per hour
int numDeps; // number of dependents
int type; // employee type
transNum = 0;
dataFile >> id;
dataFile.ignore(); // discard space before name
dataFile.getline( name, '#');
dataFile >> hourlyPay >> numDeps >> type;
}
I need it to read the first number, read the name, then read the last 3 numbers. After every name (maximum 20 characters) there is a # symbol where we should stop reading the name. I've tried adjusting the size of my char array for my string and other small fixes but nothing works. I realize that I will only get 1 line right now... I was just trying to get the first line to work before I made a loop to grab the other lines.
istream:getline needs a length parameter when used with a char array. Currently it is using '#' as the length value and using the default delimiter.
Change your code to
dataFile.getline( name, sizeof name, '#');
alternatively, use a std:string as the parameter to getline, then you don't need to specify a maximum size.
You're very close. The problem is likely to be the line
dataFile.ignore();
By default, ignore ignores everything up to EOF. What you want to do instead is ignore up to some number of characters until the next space. So that call would instead be:
datafile.ignore(100, ' ');
Where 100 is a purely arbitrary choice of number. Substitute your own rational value.
Next is your use of getline which must be told how many characters to read. Since your buffer is 20 characters, you need to inform getline like so:
getline(name, 20, '#');