user589321
user589321

Reputation: 109

Eliminating the extra copy when using getline + istringstream to parse cin inputs?

As my example, I am reading input in a CSV format. I need to take a line as input and then parse it.

Example

The standard suggestion for parsing lines of std::cin inputs looks like the following:

#include <iostream>
#include <string>
#include <sstream>

int main() {
    std::string inp;
    std::getline(std::cin, inp);

    std::istringstream inp_stream{ inp };

    std::string word_1;
    std::string word_2;
    std::string word_3;

    std::getline(inp_stream, word_1, ',');
    std::getline(inp_stream, word_2, ',');
    std::getline(inp_stream, word_3);

    std::cout << word_1 << "\n";
    std::cout << word_2 << "\n";
    std::cout << word_3;
}

The input hello,stack,overflow gives output

hello
stack
overflow

as expected.

The Problem

My problem with this method is that it seems to require an unnecessary copy of the input string. The string is copied from the input buffer to inp and copied again from inp to inp_stream. I'm sure this second copy is necessary to support the istringstream functionality, but it seems unnecessary to put the line in a std::string in the first place.

It would be nice if I could simply copy the input from the buffer to the istringstream. Can I eliminate the extra copy?

A Bad Solution

One bad solution would be to skip the istringstream by doing the following:

#include <iostream>
#include <string>
#include <sstream>

int main() {
    std::string word_1;
    std::string word_2;
    std::string word_3;

    std::getline(std::cin, word_1, ',');
    std::getline(std::cin, word_2, ',');
    std::getline(std::cin, word_3);

    std::cout << word_1 << "\n";
    std::cout << word_2 << "\n";
    std::cout << word_3;
}

Input

I am,

a
user,

gives output

I am


a
user

As you can see, the input was not in CSV format.

Upvotes: 0

Views: 26

Answers (0)

Related Questions