gpt4 book ai didi

c++ - 如何使用输入流重载将项目插入类中的映射成员?

转载 作者:行者123 更新时间:2023-11-30 03:36:42 26 4
gpt4 key购买 nike

我有 C++ 类 Question 来保存文件 questions.txt 中的多项选择题和答案的数据:

更新: 我已经更新了 &operator>> 运算符重载我有一个:

  1. 只插入2道选择题“阅读第一题”中的第一道选择题

questions.txt 文件中的数据:

A programming language is used in this Course? 3

1. C
2. Pascal
3. C++
4. Assembly

What compiler can you use to compile the programs in this Course? 4

1. Dev-C++
2. Borland C++Builder
3. Microsoft Visual C++
4. All of the above

我正在尝试将多个答案插入到 map 中。我只想问一下如何重载 operator>> 以迭代多个答案以将它们插入到 map 中:

#include <string>
#include <iostream>
#include <sstream>
#include <map>
using namespace std;
class Question
{
string question;
int correctIndex;
map<int,string> answers;


friend std::istream &operator>>(std::istream &is, Question &q) {
getline(is, q.question, '?'); // stops at '?'
is>> q.correctIndex;
string line;
while (getline(is, line) && line.empty()) // skip leading blank lines
;
while (getline(is,line) && !line.empty()) // read until blank line
{
int id;
string ans;
char pt;
stringstream sst(line); // parse the line;
sst>>id>>pt; // take number and the following point
if (!sst || id==0 || pt!='.')
cout << "parsing error on: "<<line<<endl;
else {
getline (sst, ans);
q.answers[id] = ans;
}
}
return is;
}
};

int main()
{
ifstream readFile("questions.txt");//file stream
vector<Question> questions((istream_iterator<Question>(readFile)), istream_iterator<Question>());
}

最佳答案

您的代码有两个问题:跳过第一个答案并通读文件末尾。

在这对循环中:

while (getline(is, line) && line.empty())  // skip leading blank lines
;
while (getline(is,line) && !line.empty()) // read until blank line
{

第一个非空 line 将终止第一个循环,但随后您会立即再次调用 getline() 而无需实际读取其任何内容。这将跳过第一个答案选择。您需要确保您实际上并没有在第一次调用 getline()。有点像……

// skip leading blank lines
while (getline(is, line) && line.empty()) {
;
}
for (; is && !line.empty(); getline(is, line)) {
// ...
}

但第二个也是更大的问题是,如果您通读文件末尾(就像您的代码现在所做的那样),最后一个 operator>> 将导致 istreameof(),这将忽略您流式传输的最后一个 Question。这很棘手,因为您有一个可变长度的输入流 - 我们不知道何时用完输入,直到我们实际用完输入。

值得庆幸的是,我们可以更简单地完成所有事情。首先,我们不会读取输入的末尾来触发错误,而是使用第一次读取来让我们停止:

friend std::istream &operator>>(std::istream &is, Question &q) {
if (!getline(is, q.question, '?')) { // stops at '?'
return is;
}

这样,如果我们早点到达 EOF,我们就会早点停止。对于其余的,我们可以通过使用 skipws() 来大大简化阅读。 .我们可以让 operator>> 跳过空行,而不是手动循环空行(这很难正确执行)。

当我们读完所有内容时,我们只是退出错误标志 - 因为我们不想要 fail()(如果我们尝试读取下一个索引,而它实际上是下一个问题)或 eof()(我们完成了)被触发。

总计:

friend std::istream &operator>>(std::istream &is, Question &q) {
if (!getline(is, q.question, '?')) { // stops at '?'
return is;
}

is >> q.correctIndex;

int id;
char pt;
string ans;

is >> skipws;
while (is >> id >> pt && getline(is, ans)) {
q.answers[id] = ans;
}

// keep the bad bit, clear the rest
is.clear(is.rdstate() & ios::badbit);
return is;
}

现在这也有点不完整。如果您没有读入 answers 任何与 correctIndex 匹配的内容,也许您想指出错误?在这种情况下,您也可以设置 ios::failbit

关于c++ - 如何使用输入流重载将项目插入类中的映射成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40568529/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com