从 cin 读取 getline 到字符串流 (C++)

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

所以我正在尝试从标准输入中读取这样的输入(使用 cin):

Adam English 85
Charlie Math 76
Erica History 82
Richard Science 90

我的目标是最终将每个数据片段存储在我创建的数据结构中它自己的单元格中,所以基本上我想解析输入,以便每个数据片段都是独立的。由于每一行输入都是由用户一次输入一个,所以每次我都会得到一整行我需要解析的输入。目前我正在尝试这样的事情:

stringstream ss;
getline(cin, ss);

string name;
string course;
string grade;
ss >> name >> course >> grade;

我遇到的错误是 XCode 告诉我没有对 getline 的匹配函数调用,这让我很困惑。我已经包含了 string 库,所以我猜这个错误与使用 getlinecin 读入到 stringstream 有关?如有任何帮助,我们将不胜感激。

您可以只使用 cin >> name >> course >> grade;,因为 >> 无论如何都会读取到空白。

你快到了,这个错误很可能是1引起的,因为你试图用第二个参数stringstream调用getline,只需做一个稍微修改并首先将 std::cin 中的数据存储在 string 中,然后用它来初始化 stringstream,您可以从中提取输入:

// 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.假设您包括:

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

using namespace std;

你不能std::getline()一个std::stringstream;只有一个std::string。读取为字符串,然后使用字符串流对其进行解析。

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 );
}

希望对您有所帮助。

您的代码中没有 using namespace std,或者您没有完全限定对 std 命名空间中带有 std:: 前缀的 API 的调用,例如 std::getline()。下面的解决方案改为解析 CSV 以标记其中包含空格的值。标准输入提取、解析 CSV 以及将成绩从字符串转换为整数的逻辑都是分开的。 regex_token_iterator 用法可能是最复杂的部分,但它大部分使用非常简单的正则表达式。

// 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, "");
}

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();
      }
   }
}