Nader
Nader

Reputation: 55

getline() not filling the whole string array

I wrote this code to read N lines from console input and put it into array of string, but it's reading N-1 lines Any suggestions ?

#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;

int main()
{
int test;
cin>>test;
string *cases=new string[test];
for(int i=0;i<test;i++)
{
    getline(cin,cases[i],'\n');
}

for(int i=0;i<test;i++)
{
    cout<<cases[i]<<endl;
}

system("pause");
return 0;
}

Upvotes: 1

Views: 466

Answers (1)

BoBTFish
BoBTFish

Reputation: 19767

Lets say your input is like this:

2\n
line 0\n
line 1\n

Then after cin>>test, there is an empty line at the top:

\n
line 0\n
line 1\n

Using >> only reads the bit it is interested in (i.e. the int) then leaves anything else behind on the stream (in this case, just the \n but think about it, there might be all kinds of stuff on the line). getline reads everything up to the \n then removes the \n from the stream. So after the first getline, the remaining input is:

line 0\n
line 1\n

and cases[0] contains "" (i.e. an empty string).

Then after the next getline:

remaining input:
line 1\n

and

cases[0]: ""
cases[1]: "line 0"

Then the loop stops, because it has read 2 lines. That's what's wrong. Fixing it is another matter. I prefer just to avoid mixing >> and getline. But you could do something to clear that trailing \n off the stream.

EDIT: You might also do well to read up on std::vector (that documentation might be a bit technical - search for tutorials) and the evils of using namespace std;

I put together one way of fixing it. Note stoi is c++11 only. If you don't have that available, you could try a stringstream with >>, or atoi.

#include <iostream>
#include <vector>
#include <string>
int main()
{
    int inLines = 0;
    //std::cin >> inLines;
    std::string countLine;
    std::getline(std::cin, countLine);
    try
    {
        inLines = std::stoi(countLine);
    }
    catch (...)
    {
        std::cout << "First line must be an integer\n";
        return 1;
    }
    std::vector<std::string> lines(inLines);

    for (int i = 0; i < inLines; ++i)
    {
        std::getline(std::cin, lines[i]);
    }

    for ( auto & s : lines )
    {
        std::cout << s << '\n';
    }
    return 0;
}

Upvotes: 3

Related Questions