对c++来说相对较新。
我很难理解compare((函数返回1而不是0的问题。
我有一个程序,可以读取一个文本文件,其中包含任意数量的问答。其格式如下:
Q: How many days in a week?
A: seven
我有三个文件,main.cpp、Quiz.cpp和Quiz.h:
main.cpp:
#include <iostream>
#include <vector>
#include <fstream>
#include <algorithm>
#include <ctime>
#include <cstdlib>
#include "Quiz.h"
using namespace std;
int main(int argc, char* argv[]){
srand(unsigned(time(0)));
vector<Quiz> quizVector;
ifstream inputQuiz;
inputQuiz.open(argv[1]);
string q, a;
int questionCount = 0;
if(inputQuiz.is_open()){
getline(inputQuiz, q);
getline(inputQuiz, a);
while(!inputQuiz.eof()){
Quiz *instance = new Quiz(q, a);
quizVector.push_back(*instance);
questionCount++;
getline(inputQuiz, q);
getline(inputQuiz, a);
}
}
random_shuffle(quizVector.begin(), quizVector.end());
string userInput;
for(int i = 0; i < questionCount; i++){
cout << quizVector[i].getQuestion() << endl;
cout << "A: ";
getline(cin, userInput);
if(quizVector[i].getAnswer().compare("A: " + userInput) == 0){
cout << "Correct." << endl;
}
else{
cout << "Incorrect." << endl;
}
}
return 0;
}
测验:
#include <string>
#include "Quiz.h"
int Quiz::score = 0;
std::string Quiz::getQuestion(){
return question;
}
std::string Quiz::getAnswer(){
return answer;
}
测验h:
#ifndef QUIZ_H
#define QUIZ_H
class Quiz{
private:
std::string question {""};
std::string answer {""};
public:
Quiz() = default;
Quiz(std::string q, std::string a) : question {q}, answer {a} {}
std::string getQuestion();
std::string getAnswer();
};
#endif
我的问题在于main.cpp:
for(int i = 0; i < questionCount; i++){
cout << quizVector[i].getQuestion() << endl;
cout << "A: ";
getline(cin, userInput);
if(quizVector[i].getAnswer().compare("A: " + userInput) == 0){
cout << "Correct." << endl;
}
else{
cout << "Incorrect." << endl;
}
}
当我输入每个问题对应的正确答案时,compare((不会返回0,但始终返回1。文本文件中每行的开头或结尾都没有前导空格或尾随空格。我是否误解了getline((或compare((的工作原理?是别的东西吗?感谢您的帮助!
我看到这个代码有很多问题:
-
std::random_shuffle()
在C++14中已弃用,在C++17中已删除,请改用std::shuffle()
。 -
在使用
argv
之前,您没有验证它是否包含输入参数。 -
您在
while
循环中使用eof()
是错误的。例如,如果文件中的最后一个问题/答案对由EOF而不是换行符终止,getline()
仍然会将问题/答案返回给您,但它也会在流上设置eofbit
标志,这将导致eof()
返回true
,因此您将跳过将最后一个对保存到vector
中。从技术上讲,在这种情况下,流还没有处于故障状态(请参阅https://en.cppreference.com/w/cpp/io/basic_ios/eof),所以如果最后一对以EOF而不是换行符结束,则不应该跳过它。 -
您的
while
循环正在泄漏内存。 -
您根本不需要
questionCount
,请使用quizVector.size()
。或者更好的是range-for
循环。 -
您根本不需要使用
compare()
,而是可以使用operator==
。但是,如果确实使用compare()
,则应考虑到它是区分大小写的(与operator==
一样(。您还应该利用compare()
允许您指定一个索引来开始比较,这样您就可以忽略存储的答案中的A:
前缀(或者,在Quiz
的构造函数中存储问题/答案时,您可以去掉Q:
和A:
前缀(。否则,您可以使用编译器的strcmpi()
函数(如果它提供的话(。
试试类似的东西:
#include <iostream>
#include <vector>
#include <fstream>
#include <algorithm>
#include <random>
#include <cctype>
#include "Quiz.h"
using namespace std;
string toLowercase(string s) {
transform(s.begin(), s.end(), s.begin(),
[](unsigned char c){ return tolower(c); }
);
return s;
}
int main(int argc, char* argv[]){
if (argc < 2){
cerr << "Please specify a file to open!" << endl;
return 0;
}
ifstream inputQuiz(argv[1]);
if (!inputQuiz.is_open()) {
cerr << "Can't open the file!" << endl;
return 0;
}
vector<Quiz> quizVector;
string q, a, userInput;
while (getline(inputQuiz, q) && getline(inputQuiz, a)) {
quizVector.emplace_back(q, a);
}
random_device rd;
mt19937 g(rd());
shuffle(quizVector.begin(), quizVector.end(), g);
for(auto &quiz : quizVector){
cout << quiz.getQuestion() << endl;
cout << "A: ";
getline(cin, userInput);
userInput = toLowercase(userInput);
a = toLowercase(quiz.getAnswer());
if (a == ("a: " + userInput)) {
// or:
// if (a.compare(2, string::npos, userInput) == 0) {
// or, if you strip off "A:" beforehand:
// if (a == userInput) {
cout << "Correct." << endl;
}
else {
cout << "Incorrect." << endl;
}
}
return 0;
}