初步体验Qt Creator
用途:练习20以内2位数乘法速算的程序
功能1:支持用户设定题目数量
cpp
std::cout << "请输入本次练习题目数量:";
int numProblems = 0;
std::string num;
std::cin >> num;
try {
numProblems = std::stoi(num);
MathQuiz quiz(numProblems);
quiz.runQuiz();
} catch (const std::invalid_argument& e) {
std::cerr << "请输入合法的整数结果!\n";
continue;
}
功能2:支持随机生成期望数量的题目
cpp
void MathQuiz::generateProblems() {
for (int i = 0; i < numProblems; i++) {
int randomValue1 = generateRandomValue();
int randomValue2 = generateRandomValue();
problems.emplace_back(randomValue1, randomValue2);
}
}
int MathQuiz::generateRandomValue() { return randomGenerator.bounded(10, 21); }
功能3:支持判断用户输入结果的准确性
cpp
bool MathQuiz::promptAndCheckAnswer(int value1, int value2, int index) {
std::cout << std::format("{}-{} 请计算:{}×{}=", index, numProblems, value2,
value1);
std::string str;
int result = 0;
std::cin >> str;
try {
result = std::stoi(str);
} catch (const std::invalid_argument& e) {
std::cerr << "请输入合法的整数结果!\n";
}
return result == value2 * value1;
}
功能4:循环出题,并支持记录计算错误的题目
cpp
std::map<int, std::string> incorrectProblems;
for (int i = 0; i < numProblems; i++) {
const auto& problem = problems[i];
bool correct = false;
while (!correct) {
correct = promptAndCheckAnswer(problem.first, problem.second, i + 1);
if (!correct) {
std::cout << "回答错误,请再试一次。\n";
incorrectProblems.insert(std::pair<int, std::string>(
i + 1, std::format("{}×{}", problem.first, problem.second)));
} else {
if (incorrectProblems.find(i + 1) == incorrectProblems.end()) {
numCorrect++;
}
break;
}
}
}
功能5:支持统计正确题目数、平均计算耗时和总计耗时
cpp
void MathQuiz::printResults(double elapsedTime) {
double correctPercent = numCorrect * 100 / numProblems;
QTextStream out(stdout);
QString outstr =
QString(
"共%2题,答对%1题,正确率:%3%,平均用时:%4秒,累计用时:%5秒。\n")
.arg(numCorrect)
.arg(numProblems)
.arg(correctPercent)
.arg(elapsedTime / numProblems)
.arg(elapsedTime);
out << outstr;
}
程序结构:
main.cpp主程序
cpp
#include <windows.h>
#include <QCoreApplication>
#include <iostream>
#include "mathquiz.h"
int main() {
SetConsoleOutputCP(CP_UTF8);
while (true) {
std::cout << "请输入本次练习题目数量:";
int numProblems = 0;
std::string num;
std::cin >> num;
try {
numProblems = std::stoi(num);
MathQuiz quiz(numProblems);
quiz.runQuiz();
} catch (const std::invalid_argument& e) {
std::cerr << "请输入合法的整数结果!\n";
continue;
}
std::cout << "是否继续练习? (y/n):";
std::string yn;
std::cin >> yn;
if (yn != "y" && yn != "Y") break;
}
return 0;
}
mathquiz.cpp,一个计算功能类
cpp
#include "mathquiz.h"
#include <iostream>
MathQuiz::MathQuiz(int numProblems) : numCorrect(0), numProblems(numProblems) {
randomGenerator.seed(QTime::currentTime().msec());
generateProblems();
}
void MathQuiz::runQuiz() {
QTime startTime = QTime::currentTime();
std::map<int, std::string> incorrectProblems;
for (int i = 0; i < numProblems; i++) {
const auto& problem = problems[i];
bool correct = false;
while (!correct) {
correct = promptAndCheckAnswer(problem.first, problem.second, i + 1);
if (!correct) {
std::cout << "回答错误,请再试一次。\n";
incorrectProblems.insert(std::pair<int, std::string>(
i + 1, std::format("{}×{}", problem.first, problem.second)));
} else {
if (incorrectProblems.find(i + 1) == incorrectProblems.end()) {
numCorrect++;
}
break;
}
}
}
QTime endTime = QTime::currentTime();
double elapsedTime = startTime.msecsTo(endTime) / 1000.0;
printResults(elapsedTime);
printIncorrectProblems(incorrectProblems);
}
void MathQuiz::generateProblems() {
for (int i = 0; i < numProblems; i++) {
int randomValue1 = generateRandomValue();
int randomValue2 = generateRandomValue();
problems.emplace_back(randomValue1, randomValue2);
}
}
int MathQuiz::generateRandomValue() { return randomGenerator.bounded(10, 21); }
bool MathQuiz::promptAndCheckAnswer(int value1, int value2, int index) {
std::cout << std::format("{}-{} 请计算:{}×{}=", index, numProblems, value2,
value1);
std::string str;
int result = 0;
std::cin >> str;
try {
result = std::stoi(str);
} catch (const std::invalid_argument& e) {
std::cerr << "请输入合法的整数结果!\n";
}
return result == value2 * value1;
}
void MathQuiz::printResults(double elapsedTime) {
double correctPercent = numCorrect * 100 / numProblems;
QTextStream out(stdout);
QString outstr =
QString(
"共%2题,答对%1题,正确率:%3%,平均用时:%4秒,累计用时:%5秒。\n")
.arg(numCorrect)
.arg(numProblems)
.arg(correctPercent)
.arg(elapsedTime / numProblems)
.arg(elapsedTime);
out << outstr;
}
void MathQuiz::printIncorrectProblems(
const std::map<int, std::string>& incorrectProblems) {
if (incorrectProblems.empty()) {
return;
}
std::cout << "回答错误的题目:\n";
int i = 1;
for (const auto& it : incorrectProblems) {
const auto& problem = problems[it.first - 1];
std::cout << "题目 " << i << ": " << it.second << "="
<< (problem.first * problem.second) << "\n";
i++;
}
}
mathquiz.h头文件
cpp
#ifndef MATHQUIZ_H
#define MATHQUIZ_H
#include <QRandomGenerator>
#include <QTime>
#include <vector>
class MathQuiz {
public:
MathQuiz(int numProblems);
void runQuiz();
private:
void generateProblems();
int generateRandomValue();
bool promptAndCheckAnswer(int value1, int value2, int index);
void printResults(double elapsedTime);
void printIncorrectProblems(
const std::map<int, std::string>& incorrectProblems);
QRandomGenerator randomGenerator;
int numCorrect;
int numProblems;
std::vector<std::pair<int, int>> problems;
};
#endif // MATHQUIZ_H
运行效果
遇到问题总结:
Qt Creator编写Console程序,运行时没反应,应勾选下面选项
Qt Creator编写Console程序,汉字输出乱码
原因1:默认字符输出位置设置的值与Windows控制台默认字符集(GBK)不符
默认字符输出查看与修改
确定控制台窗口使用的编码格式:
原因2:文件编码格式与系统不兼容
原因3:部分库默认使用UTF-8,输出应转码,比如QTextStream
cpp
QTextStream out(stdout);
out.setEncoding (QStringConverter::System);
还有个方法,添加windows.h的引用,并在main开始时,添加:
SetConsoleOutputCP(CP_UTF8);
注意:将所有源代码以及系统文件编辑器默认编码均修改为UTF-8即可