一个简单的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即可

相关推荐
郝学胜-神的一滴9 分钟前
线程同步:并行世界的秩序守护者
java·linux·开发语言·c++·程序人生
superman超哥9 分钟前
Rust 移动语义(Move Semantics)的工作原理:零成本所有权转移的深度解析
开发语言·后端·rust·工作原理·深度解析·rust移动语义·move semantics
青茶36011 分钟前
【js教程】如何用jq的js方法获取url链接上的参数值?
开发语言·前端·javascript
赵民勇12 分钟前
rcc (Qt Resource Compiler) 详细指南
qt
superman超哥21 分钟前
Rust 所有权转移在函数调用中的表现:编译期保证的零成本抽象
开发语言·后端·rust·函数调用·零成本抽象·rust所有权转移
xiaowu08021 分钟前
C# 把dll分别放在指定的文件夹的方法
开发语言·c#
mg66828 分钟前
0基础开发学习python工具_____用 Python + Pygame 打造绚丽烟花秀 轻松上手体验
开发语言·python·学习·pygame
CodeOfCC40 分钟前
C++ 实现ffmpeg解析hls fmp4 EXT-X-DISCONTINUITY并支持定位
开发语言·c++·ffmpeg·音视频
ghie909040 分钟前
基于LSB匹配的隐写术MATLAB实现
开发语言·计算机视觉·matlab
Lhan.zzZ42 分钟前
Qt绘制残留问题排查与修复日志
开发语言·数据库·qt