1

I was learning how to read strings with getline function.

I know that getline function read string as far as we don't hit enter or the size value in the getline parameter go cross. As far as I tried getline function to read one line of string I had not faced any problem.

But when I was trying to read two line of string one after another in two different char array i got the output that was not expected to me. To understand my question follow bellow lines

#include <iostream>
using namespace std;
int main()
{
    char line1[10];
    char line2[10];
    cin.getline(line1,7);
    cin.getline(line2,7);
    cout << "\nline1 =" << line1 <<endl;
    cout << "line2 =" << line2 <<endl;
}

When I ran the above program it ask me for input then I gave orange as first input and hit the enter button.

Next it ask me to give the second input .then i gave banana and hit the enter button .in this case it produce the result i expected .But if enter oranges for the first input it does not wait for me to enter the second input.

As a result line1 store orange but line2 remains blank. Now my question is that there is no wrong with line1 storing orange. But I don't understand why the line2 remains blank should not it contain the data that remains after line1 take input I mean should not line2 contain s as value.

Because orange is a 6 digit word so getline will stores the first six digit after then a null character will be added as I set the size of geline 7.

Then other remaing data will be assigend in the next call of getline function.So should not s stored in line2 as after s a new_line character is read for the first time.

Why will be line2 remain blank and why the screen doesn't stop for taking input after giving the first input?

Kamil Naja
  • 6,267
  • 6
  • 33
  • 47
  • Can you please clean up the large paragraph that constitutes the bulk of your question so that we can read it? – paddy Jul 18 '19 at 05:12
  • okk.i am trying to make it short. But i thought it was good to give full description of my problem –  Jul 18 '19 at 05:15
  • 2
    Do you understand what the second parameter to `cin.getline` does? (Nudge: Try entering `marmalade` for line 1.) – 1201ProgramAlarm Jul 18 '19 at 05:16
  • The syntax of `getline` is a little weird. What are you trying to do with the second argument `7`? – absolutelydevastated Jul 18 '19 at 05:17
  • 1
    Much like code, readability will benefit from structure and whitespace. In any case, what do you expect to happen when you specify a maximum of 7 characters to read? When you read `oranges`, that is 7, and so the return character is not read. It will be picked up by the next `getline` which will only read the return and think it's an empty string. – paddy Jul 18 '19 at 05:17
  • @absolutelydevastated i am trying to store first six digit of character in the line1 char array in case the user give more than 6 digit character –  Jul 18 '19 at 05:20
  • @1201ProgramAlarm i tried marmalade . there line1 contains marmal and line2 remain blank as my problem was –  Jul 18 '19 at 05:22
  • @paddy it makes sense your comment.but should not line2 contain abcd if i would give the first argument as orangesabcd .But it still give line1 =orange line2 = it could be happen i could not understand your logic .But can you show me how will store two string in two line variable –  Jul 18 '19 at 05:32
  • I believe the answer written by user4581301 describes why. – paddy Jul 18 '19 at 05:35

1 Answers1

5

std::istream::getline is being overloaded with data.

According to cppreference,

Behaves as UnformattedInputFunction. After constructing and checking the sentry object, extracts characters from *this and stores them in successive locations of the array whose first element is pointed to by s, until any of the following occurs (tested in the order shown):

  • end of file condition occurs in the input sequence (in which case setstate(eofbit) is executed)
  • the next available character c is the delimiter, as determined by Traits::eq(c, delim). The delimiter is extracted (unlike basic_istream::get()) and counted towards gcount(), but is not stored.
  • count-1 characters have been extracted (in which case setstate(failbit) is executed).

Emphasis mine.

cin.getline(line1,7);
//                ^ This is count

can read only 6 characters with the 7th reserved for the null terminator. "oranges" is seven characters, and this places cin in a non-readable error state that must be cleared before reading can be continued. Reading of the second line

cin.getline(line2,7);

instantly fails and no data is read.

The obvious solution is

cin.getline(line1, sizeof(line1));

to take advantage of the whole array. But...

Any IO transaction should be tested for success, so

if (cin.getline(line1, sizeof(line1)))
{
    // continue gathering 
}
else
{
    // handle error
}

is a better option.

Better still would be to use std::getline and std::string to almost eliminate the size constraints.

Community
  • 1
  • 1
user4581301
  • 33,082
  • 7
  • 33
  • 54