在c++中使用std::string::compare()返回值时出现问题



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

相关内容

  • 没有找到相关文章

最新更新