Reading getline from cin into a stringstream (C++)

和自甴很熟 提交于 2019-11-29 07:16:09

You are almost there, the error is most probably1 caused because you are trying to call getline with second parameter stringstream, just make a slight modification and store the data within the std::cin in a string first and then used it to initialize a stringstream, from which you can extract the input:

// read input
string input;
getline(cin, input);

// initialize string stream
stringstream ss(input);

// extract input
string name;
string course;
string grade;

ss >> name >> course >> grade;

1. Assuming you have included:

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

using namespace std;

You cannot std::getline() a std::stringstream; only a std::string. Read as a string, then use a stringstream to parse it.

struct Student
{
  string   name;
  string   course;
  unsigned grade;
};

vector <Student> students;
string s;
while (getline( cin, s ))
{
  istringstream ss(s);
  Student student;
  if (ss >> student.name >> student.course >> student.grade)
    students.emplace_back( student );
}

Hope this helps.

You can just use cin >> name >> course >> grade; because >> will read until whitespace anyway.

Either you don't have a using namespace std in your code or you're not fully qualifying calls made to the API's in the std namespace with an std:: prefix, for example, std::getline(). The solution below parses CSV instead to tokenize values that have whitespace in them. The logic for stdin extraction, parsing the CSV, and converting grade from string to int are all separated. The regex_token_iterator usage is probably the most complicated part, but it uses pretty simple regex for the most part.

// foo.txt:

// Adam,English,85
// Charlie,Math,76
// Erica,History,82
// Richard,Science,90
// John,Foo Science,89

// after compiling to a.exe, run with:
// $ ./a.exe < foo.txt 

// output
// name: Adam, course: English, grade: 85
// name: Charlie, course: Math, grade: 76
// name: Erica, course: History, grade: 82
// name: Richard, course: Science, grade: 90
// name: John, course: Foo Science, grade: 89

#include <iostream>
#include <sstream>
#include <regex>
#include <vector>

using namespace std;

typedef unsigned int uint;

uint stoui(const string &v) {
   uint i;
   stringstream ss;
   ss << v;
   ss >> i;
   return i;
}

string strip(const string &s) {
   regex strip_pat("^\\s*(.*?)\\s*$");
   return regex_replace(s, strip_pat, "$1");
}

vector<string> parse_csv(string &line) {
   vector<string> values;
   regex csv_pat(",");
   regex_token_iterator<string::iterator> end;
   regex_token_iterator<string::iterator> itr(
      line.begin(), line.end(), csv_pat, -1);
   while (itr != end)
      values.push_back(strip(*itr++));
   return values;
}

struct Student {
   string name;
   string course;
   uint grade;
   Student(vector<string> &data) : 
      name(data[0]), course(data[1]), grade(stoui(data[2])) {}
   void dump_info() {
      cout << "name: " << name << 
      ", course: " << course << 
      ", grade: " << grade << endl;
   }
};

int main() {
   string line;
   while (getline(cin, line)) {
      if (!line.empty()) {
         auto csv = parse_csv(line);
         Student s(csv);
         s.dump_info();
      }
   }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!