2016-03-13 19 views
4

所以我试图从标准输入读取输入这样的(使用cin):可以从cin读函数getline成字符串流(C++)

亚当英语85
查理数学76
埃里卡历史82
理查德科学90

我的目标是最终存储在我创建了一个数据结构自身的细胞每一个数据块,所以基本上我想要解析输入所以每个馅饼数据的ce是个人的。由于每行输入都由用户一次输入一次,每当我得到需要解析的整行输入时。目前,我想是这样的:

stringstream ss; 
getline(cin, ss); 

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

我遇到的错误是,Xcode是告诉我没有匹配的函数调用getline这是混淆了我。我已经包含了string库,所以我猜这个错误与使用getlinecin读入stringstream有关?任何帮助在这里将不胜感激。

+0

您是否意识到只有在名称和课程不包含空格的情况下,您的程序才会有效?它会失败的“约翰史密斯英语”或“亚当计算机科学”... –

回答

8

你就要成功了,错误是最有可能造成的,因为你试图调用getline与第二个参数stringstream,只是稍作修改和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; 
2

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

+2

虽然添加一行一行的解析层通常实际上是一件好事。 –

+0

这对我来说是最好的答案 –

7

你不能std::getline() a std::stringstream;只有一个std::string。以字符串形式读取,然后使用stringstream来解析它。

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

希望这会有所帮助。

0

要么你没有在你的代码using namespace std,或者你没有完全限定与std::前缀API的提出std名称空间中调用,例如,std::getline()。下面的解决方案解析CSV而不是标记其中包含空格的值。 stdin提取,解析CSV以及将字符串转换为int的逻辑都是分开的。 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, "$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(); 
     } 
    } 
}