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

相关推荐
Mr. zhihao7 分钟前
装饰器模式详解:动态扩展对象功能的优雅解决方案
java·开发语言·装饰器模式
zyhomepage7 分钟前
科技的成就(六十四)
开发语言·人工智能·科技·算法·内容运营
Ethan Wilson13 分钟前
C++/QT可用的websocket库
开发语言·c++·websocket
小宇1 小时前
The valid characters are defined in RFC 7230 and RFC 3986
java·开发语言·后端·tomcat
尘浮生1 小时前
Java项目实战II基于Spring Boot的美食烹饪互动平台的设计与实现(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·微信小程序·小程序·美食
杨荧1 小时前
【JAVA毕业设计】基于Vue和SpringBoot的校园美食分享平台
java·开发语言·前端·vue.js·spring boot·java-ee·美食
糊涂君-Q1 小时前
Python小白学习教程从入门到入坑------第十九课 异常模块与包【下】(语法基础)
开发语言·python·学习·程序人生·改行学it
爱编程的小新☆1 小时前
Java篇图书管理系统
java·开发语言·学习
极客代码1 小时前
C/C++ 随机数生成方法
c语言·开发语言·c++·算法
API199701081102 小时前
京东平台接口技术详解及示例代码
开发语言·前端·python