一个简单的Qt Console Application计算练习程序

初步体验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即可

相关推荐
用户8055336980315 小时前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner15 小时前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz6 天前
QML Hello World 入门示例
qt
xcyxiner9 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner9 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner10 天前
DicomViewer (添加模型类)3
qt
xcyxiner10 天前
DicomViewer (目录调整) 2
qt
xcyxiner10 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00612 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术12 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript