1

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;
}
Nader
  • 55
  • 1
  • 6
  • give a sample output explaining what is wrong – uba Mar 11 '13 at 11:39
  • 1
    It's the combination of `>>` and `getline`. The rest of the line (which actually probably contains nothing) after you enter the `int` for the size is being read into `cases[0]`. I always find it's simplest just not to mix use of `>>` and `getline`. – BoBTFish Mar 11 '13 at 11:41

1 Answers1

3

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;
}
Community
  • 1
  • 1
BoBTFish
  • 19,167
  • 3
  • 49
  • 76
  • 1
    Thanks for explaining the problem, i fixed it with scanf("%d\n",&test); Is there a better way ? – Nader Mar 11 '13 at 12:04
  • I added one possible way of doing it. Using `scanf` fixes this particular problem, but still basically means you are mixing up your input methods, which can cause trouble. – BoBTFish Mar 11 '13 at 12:11