roycf123's blog

By roycf123, 10 months ago, In English

We know that in python, we can use the following to get a list of integers (space separated) in a line:

arr = list(map(int,input().split()))

This doesn't require us to input the number of integers in the line before. In C++ however, it is not that easy. But fortunately for us, most cp questions give the input n (size of the vector).

What if we don't get the size beforehand, huh? Here's a possible fix....

#define ll long long

istream& operator>>(istream& stream,vector<ll>& a) {
    string line;
    getline(stream, line);
    istringstream lineStream(line);
    ll x;
    while(lineStream >> x) a.push_back(x);
    return stream;
}

.

How to use?

Alternatively we can use the following template and normally take vector input: (credit: -is-this-fft)

template<typename T>
istream& operator>> (istream& stream, vector<T> &a) {
  a.clear(); // remove whatever was in a before
  
  string line;
  do {
    if (stream.eof())
      return stream; // if the stream has ended, just let a be empty
    
    getline(stream, line);
  } while (line.empty());
  
  istringstream line_stream (line);
  T x;
  while(line_stream >> x)
    a.push_back(x);
  
  return stream;
}

P.S: I have tried my best to keep it error-free, but if you find any mistakes, feel free to highlight in the comment section...

  • Vote: I like it
  • +11
  • Vote: I do not like it

»
10 months ago, # |
  Vote: I like it +2 Vote: I do not like it

Auto comment: topic has been updated by roycf123 (previous revision, new revision, compare).

»
10 months ago, # |
  Vote: I like it 0 Vote: I do not like it

Are you sure this is working because its not working for input like

1 2 3 4 5

but working for

5

1 2 3 4 5

»
10 months ago, # |
  Vote: I like it +10 Vote: I do not like it

The use of cin.ignore here is dubious (also, it should be stream.ignore because you're taking any stream as input, not necessarily cin). If you do cin >> a two times in a row, you will eat the line between them: e.g

code
input
output

Similarly, if you do cin >> a at the start of the code, you will eat the first line of the input.

I do understand why you put it there though: if you read e.g. a single integer from cin, then after that, the \n character at the end of the line has not yet been read from the stream, so your call to getline will simply be an empty string (or a string consisting of whatever was between what you already read and the \n character, possibly just whitespace).

The simplest way to fix this is to remove the cin.ignore line, and to remember to do an ignore between reading something from cin in the "regular" way and reading a line from cin that way. There are other ways to do this, but they all make assumptions about how exactly you want to read the input. The simplest way is to simply skip over the line if it is empty:

template<typename T>
istream& operator>> (istream& stream, vector<T> &a) {
  a.clear(); // remove whatever was in a before
  
  string line;
  do {
    if (stream.eof())
      return stream; // if the stream has ended, just let a be empty
    
    getline(stream, line);
  } while (line.empty());
  
  istringstream line_stream (line);
  T x;
  while(line_stream >> x)
    a.push_back(x);
  
  return stream;
}
  • »
    »
    10 months ago, # ^ |
      Vote: I like it +1 Vote: I do not like it

    Sure thank you, and I will include your template in the main blog...