C++学习之路(十二)C++ 用Qt5实现一个工具箱(增加一个XML文本格式化功能)- 示例代码拆分讲解

上篇文章,我们用 Qt5 实现了在小工具箱中添加了《进制转换器功能》功能。为了继续丰富我们的工具箱,今天我们就再增加一个平时经常用到的功能吧,就是「 XML文本格式化 」功能。下面我们就来看看如何来规划开发一个这样的小功能并且添加到我们的工具箱中吧。

老规矩,先看效果

正确解析的效果:

在这里插入图片描述

解析错误的效果

在这里插入图片描述


XML文本格式化功能概述

功能描述:
XML格式化工具允许用户输入未格式化的XML文本,并将其格式化为易于阅读的结构化形式。这个工具允许用户以清晰的方式查看和编辑XML数据,提高了XML文档的可读性和可维护性。

功能需求:

  1. 文本输入区域: 提供一个文本框,用于用户输入原始的未格式化XML文本。
  2. 格式化按钮: 提供一个按钮,当用户点击时,执行XML文本的格式化操作。
  3. 格式化输出区域: 显示格式化后的XML文本结果,以便用户查看和复制到其他位置。
  4. 清晰的显示效果: 格式化后的XML文本应该以良好的缩进和层级结构显示,以便用户更容易阅读和理解。

工作流程:

  1. 用户在文本框中输入未格式化的XML文本。
  2. 用户点击“格式化”按钮。
  3. 系统执行XML文本的格式化操作。
  4. 格式化后的XML文本显示在输出区域,以清晰的缩进和层级结构呈现。

优势和价值:

  • 提升可读性: 将XML文本格式化后,使其更易于阅读和理解。
  • 简化编辑和维护: 格式化的XML文档更容易编辑和维护,减少错误和混淆。

注意事项:

  • 输入的XML文本应该是有效的,不符合XML规范的文本可能会导致格式化错误。
  • 需要考虑处理可能存在的格式化异常或错误的情况,向用户提供相应的反馈或提示。

这个功能对于需要处理或查看大量XML文本的用户或开发人员非常有用,可以提高工作效率和准确性。

核心代码实现

现在进入正题,我们如何实现一个格式化XML文本的功能,而且这个功能将用一个按钮进行触发。首先,我们创建一个名为 XmlFormatter 的新类,并在 MyMainWindow 中添加一个按钮来显示和隐藏 XmlFormatter

class XmlFormatter : public QWidget {
Q_OBJECT
public:explicit XmlFormatter(QWidget *parent = nullptr) : QWidget(parent) {auto *layout = new QVBoxLayout(this);inputTextEdit = new QTextEdit(this);layout->addWidget(inputTextEdit);formatButton = new QPushButton("格式化 XML", this);connect(formatButton, &QPushButton::clicked, this, &XmlFormatter::formatXml);layout->addWidget(formatButton);outputTextEdit = new QTextEdit(this);outputTextEdit->setReadOnly(true);layout->addWidget(outputTextEdit);setLayout(layout);}private slots:void formatXml() {// 获取输入的XML文本QString inputText = inputTextEdit->toPlainText();if (!inputText.isEmpty()) {// 使用 QXmlStreamReader 读取输入的 XML 文本QXmlStreamReader reader(inputText);QString formattedXml;int indentLevel = 0;while (!reader.atEnd() && !reader.hasError()) {if (reader.isStartElement()) {formattedXml += getIndent(indentLevel) + "<" + reader.name().toString() + ">\n";++indentLevel;} else if (reader.isEndElement()) {--indentLevel;formattedXml += getIndent(indentLevel) + "</" + reader.name().toString() + ">\n";} else if (reader.isCharacters() && !reader.isWhitespace()) {formattedXml += getIndent(indentLevel) + reader.text().toString() + "\n";}reader.readNext();}if (reader.hasError()) {outputTextEdit->setText("XML 解析错误:" + reader.errorString());} else {outputTextEdit->setText(formattedXml);}} else {// 如果输入为空,则清空输出区域outputTextEdit->clear();}}static QString getIndent(int level) {return QString(level * 4, ' '); // 4空格作为缩进}private:QTextEdit *inputTextEdit;QPushButton *formatButton;QTextEdit *outputTextEdit;
};

然后,在 MyMainWindow 类中添加一个按钮和 XmlFormatter 对象,并在槽函数 toggleXmlFormatter 中切换它的显示状态。

class MyMainWindow : public QWidget {
Q_OBJECT
public:explicit MyMainWindow(QWidget *parent = nullptr) : QWidget(parent) {setWindowTitle("天河工具箱");auto *layout = new QVBoxLayout(this);// ... (之前的按钮)auto *xmlFormatterButton = new QPushButton("显示XML格式化");xmlFormatterButton->setObjectName("xmlFormatterButton");connect(xmlFormatterButton, &QPushButton::clicked, this, &MyMainWindow::toggleXmlFormatter);xmlFormatter = new XmlFormatter(this);xmlFormatter->hide();layout->addWidget(xmlFormatter);layout->addWidget(xmlFormatterButton);setLayout(layout);}private slots:void toggleXmlFormatter() {auto* curButton = findChild<QPushButton*>("xmlFormatterButton");if (xmlFormatter->isHidden()) {if (curButton) {curButton->setText("隐藏XML格式化");}xmlFormatter->show();} else {if (curButton) {curButton->setText("显示XML格式化");}xmlFormatter->hide();}}private:XmlFormatter *xmlFormatter;// ... (其他对象)
};

这样,你现在就有一个名为 XmlFormatter 的新类,它具有格式化XML文本的功能,并且通过在 MyMainWindow 中添加一个按钮可以控制其显示和隐藏。


核心代码拆分讲解

第一部分:
class XmlFormatter : public QWidget {
Q_OBJECT
public:explicit XmlFormatter(QWidget *parent = nullptr) : QWidget(parent) {auto *layout = new QVBoxLayout(this);inputTextEdit = new QTextEdit(this);layout->addWidget(inputTextEdit);formatButton = new QPushButton("格式化", this);connect(formatButton, &QPushButton::clicked, this, &XmlFormatter::formatXml);layout->addWidget(formatButton);outputTextEdit = new QTextEdit(this);outputTextEdit->setReadOnly(true);layout->addWidget(outputTextEdit);setLayout(layout);}
  • XmlFormatter是一个QWidget的子类,用于格式化XML文本。
  • 构造函数XmlFormatter创建了一个垂直布局layout,将各个控件嵌套在其中。
  • inputTextEdit是一个QTextEdit控件,用于用户输入XML文本。
  • formatButton是一个QPushButton按钮,点击后将触发格式化XML文本的槽函数。
  • outputTextEdit是一个只读的QTextEdit,用于显示格式化后的XML文本。
第二部分:

当点击格式化按钮时,formatXml() 槽函数被触发。它首先获取用户在输入文本框中输入的XML文本。接着,使用 QXmlStreamReader 对象来读取输入的XML文本。在这段代码中,QXmlStreamReader 用于遍历XML文本的各个部分。

void formatXml() {QString inputText = inputTextEdit->toPlainText();// 使用 QXmlStreamReader 读取输入的 XML 文本QXmlStreamReader reader(inputText);QString formattedXml;int indentLevel = 0;while (!reader.atEnd() && !reader.hasError()) {if (reader.isStartElement()) {formattedXml += getIndent(indentLevel) + "<" + reader.name().toString() + ">\n";++indentLevel;} else if (reader.isEndElement()) {--indentLevel;formattedXml += getIndent(indentLevel) + "</" + reader.name().toString() + ">\n";} else if (reader.isCharacters() && !reader.isWhitespace()) {formattedXml += getIndent(indentLevel) + reader.text().toString() + "\n";}reader.readNext();}if (reader.hasError()) {outputTextEdit->setText("XML 解析错误:" + reader.errorString());} else {outputTextEdit->setText(formattedXml);}
}

while循环中,程序首先检查当前的XML事件。当它遇到一个开始元素时,它会在 formattedXml 中添加该元素的标签,并增加缩进级别。当它遇到一个结束元素时,它会在 formattedXml 中添加该元素的结束标签,并减少缩进级别。最后,当遇到元素内容(characters)时,它会将内容添加到 formattedXml 中,并根据缩进级别进行缩进。

QString getIndent(int level) {return QString(level * 4, ' '); // 4空格作为缩进
}

getIndent 函数用于返回指定级别的缩进字符串,它返回一个由指定数量空格组成的字符串,以此作为 XML 格式化中的缩进。

最后,如果 QXmlStreamReader 遇到错误,它会将错误消息显示在输出文本框中;否则,将格式化后的XML显示在输出文本框中。


讲解完毕,下面是完整代码,复制到本地跑一跑吧~

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QMessageBox>
#include <QDebug>
#include <QListWidget>
#include <QClipboard>
#include <QMimeData>
#include <QTextEdit>
#include <QJsonDocument>
#include <QJsonObject>
#include <QDateTime>
#include <QLabel>
#include <QComboBox>
#include <QLineEdit>
#include <QXmlStreamReader>#define myApp (dynamic_cast<QApplication *>(QCoreApplication::instance()))class XmlFormatter : public QWidget {
Q_OBJECT
public:explicit XmlFormatter(QWidget *parent = nullptr) : QWidget(parent) {auto *layout = new QVBoxLayout(this);inputTextEdit = new QTextEdit(this);layout->addWidget(inputTextEdit);formatButton = new QPushButton("格式化 XML", this);connect(formatButton, &QPushButton::clicked, this, &XmlFormatter::formatXml);layout->addWidget(formatButton);outputTextEdit = new QTextEdit(this);outputTextEdit->setReadOnly(true);layout->addWidget(outputTextEdit);setLayout(layout);}private slots:void formatXml() {// 获取输入的XML文本QString inputText = inputTextEdit->toPlainText();if (!inputText.isEmpty()) {// 使用 QXmlStreamReader 读取输入的 XML 文本QXmlStreamReader reader(inputText);QString formattedXml;int indentLevel = 0;while (!reader.atEnd() && !reader.hasError()) {if (reader.isStartElement()) {formattedXml += getIndent(indentLevel) + "<" + reader.name().toString() + ">\n";++indentLevel;} else if (reader.isEndElement()) {--indentLevel;formattedXml += getIndent(indentLevel) + "</" + reader.name().toString() + ">\n";} else if (reader.isCharacters() && !reader.isWhitespace()) {formattedXml += getIndent(indentLevel) + reader.text().toString() + "\n";}reader.readNext();}if (reader.hasError()) {outputTextEdit->setText("XML 解析错误:" + reader.errorString());} else {outputTextEdit->setText(formattedXml);}} else {// 如果输入为空,则清空输出区域outputTextEdit->clear();}}static QString getIndent(int level) {return QString(level * 4, ' '); // 4空格作为缩进}private:QTextEdit *inputTextEdit;QPushButton *formatButton;QTextEdit *outputTextEdit;
};class NumberBaseConverter : public QWidget {
Q_OBJECT
public:explicit NumberBaseConverter(QWidget *parent = nullptr) : QWidget(parent) {auto *layout = new QVBoxLayout(this);// 横向排列的输入框和选择框auto *horizontalLayout = new QHBoxLayout();// 创建输入框并添加到水平布局inputLineEdit = new QLineEdit(this);horizontalLayout->addWidget(inputLineEdit);// 连接输入框的文本变化信号到槽函数connect(inputLineEdit, &QLineEdit::textChanged, this, &NumberBaseConverter::convertNumber);// 创建下拉选择框并添加到水平布局baseComboBox = new QComboBox(this);baseComboBox->addItem("二进制");baseComboBox->addItem("八进制");baseComboBox->addItem("十进制");baseComboBox->addItem("十六进制");horizontalLayout->addWidget(baseComboBox);// 将水平布局添加到垂直布局layout->addLayout(horizontalLayout);// 创建四个只读的输出框并添加到垂直布局binaryOutput = new QLineEdit(this);binaryOutput->setReadOnly(true);layout->addWidget(binaryOutput);octalOutput = new QLineEdit(this);octalOutput->setReadOnly(true);layout->addWidget(octalOutput);decimalOutput = new QLineEdit(this);decimalOutput->setReadOnly(true);layout->addWidget(decimalOutput);hexOutput = new QLineEdit(this);hexOutput->setReadOnly(true);layout->addWidget(hexOutput);// 连接下拉选择框的选择变化信号到槽函数,并进行初始转换connect(baseComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &NumberBaseConverter::convertNumber);convertNumber(); // 初始转换setLayout(layout); // 设置整体布局}private slots:void convertNumber() {QString inputText = inputLineEdit->text();bool ok;int base = baseComboBox->currentIndex();if (!inputText.isEmpty()) {// 根据所选进制进行转换if (base == 0) {int number = inputText.toInt(&ok, 2); // 二进制转十进制if (ok) {binaryOutput->setText(inputText);octalOutput->setText(QString::number(number, 8));decimalOutput->setText(QString::number(number));hexOutput->setText(QString::number(number, 16).toUpper());}} else if (base == 1) {// 八进制转换int number = inputText.toInt(&ok, 8);if (ok) {binaryOutput->setText(QString::number(number, 2));octalOutput->setText(inputText);decimalOutput->setText(QString::number(number));hexOutput->setText(QString::number(number, 16).toUpper());}} else if (base == 2) {// 十进制转换int number = inputText.toInt(&ok, 10);if (ok) {binaryOutput->setText(QString::number(number, 2));octalOutput->setText(QString::number(number, 8));decimalOutput->setText(inputText);hexOutput->setText(QString::number(number, 16).toUpper());}} else if (base == 3) {// 十六进制转换int number = inputText.toInt(&ok, 16);if (ok) {binaryOutput->setText(QString::number(number, 2));octalOutput->setText(QString::number(number, 8));decimalOutput->setText(QString::number(number));hexOutput->setText(inputText.toUpper());}}} else {// 如果输入为空,则清空输出binaryOutput->clear();octalOutput->clear();decimalOutput->clear();hexOutput->clear();}}private:QLineEdit *inputLineEdit;QComboBox *baseComboBox;QLineEdit *binaryOutput;QLineEdit *octalOutput;QLineEdit *decimalOutput;QLineEdit *hexOutput;
};class PlaceholderTextEdit : public QWidget {
Q_OBJECT
public:explicit PlaceholderTextEdit(const QString &placeholderText, QWidget *parent = nullptr) : QWidget(parent) {auto *layout = new QVBoxLayout(this);placeholderLabel = new QLabel(placeholderText, this);layout->addWidget(placeholderLabel);textEdit = new QTextEdit(this);layout->addWidget(textEdit);connect(textEdit, &QTextEdit::textChanged, this, &PlaceholderTextEdit::checkPlaceholder);checkPlaceholder(); // 初始检查setLayout(layout);}QString getText() const {return textEdit->toPlainText();}private slots:void checkPlaceholder() {placeholderLabel->setVisible(textEdit->toPlainText().isEmpty());}private:QLabel *placeholderLabel;QTextEdit *textEdit;
};class DateTimeTimestampConverter : public QWidget {
Q_OBJECT
public:explicit DateTimeTimestampConverter(QWidget *parent = nullptr) : QWidget(parent) {auto *layout = new QVBoxLayout(this);inputTextEdit = new PlaceholderTextEdit("在此输入日期时间或时间戳", this);layout->addWidget(inputTextEdit);convertToTimestampButton = new QPushButton("日期时间转时间戳", this);connect(convertToTimestampButton, &QPushButton::clicked, this, &DateTimeTimestampConverter::convertToTimestamp);layout->addWidget(convertToTimestampButton);convertToDateTimeButton = new QPushButton("时间戳转日期时间", this);connect(convertToDateTimeButton, &QPushButton::clicked, this, &DateTimeTimestampConverter::convertToDateTime);layout->addWidget(convertToDateTimeButton);outputTextEdit = new QTextEdit(this);outputTextEdit->setReadOnly(true);layout->addWidget(outputTextEdit);setLayout(layout);}private slots:void convertToTimestamp() {QString inputText = inputTextEdit->getText();QDateTime dateTime = QDateTime::fromString(inputText, "yyyy-MM-dd HH:mm:ss");if (dateTime.isValid()) {qint64 timestamp = dateTime.toSecsSinceEpoch();outputTextEdit->setText(QString::number(timestamp));} else {outputTextEdit->setText("无效的日期时间格式!");}}void convertToDateTime() {QString inputText = inputTextEdit->getText();bool ok;qint64 timestamp = inputText.toLongLong(&ok);if (ok) {QDateTime dateTime;dateTime.setSecsSinceEpoch(timestamp);outputTextEdit->setText("时间戳 " + inputText + " 对应的日期时间是:" + dateTime.toString("yyyy-MM-dd HH:mm:ss"));} else {outputTextEdit->setText("无效的时间戳格式!");}}private:QPushButton *convertToTimestampButton;QPushButton *convertToDateTimeButton;QTextEdit *outputTextEdit;PlaceholderTextEdit *inputTextEdit;
};class JsonFormatter : public QWidget {
Q_OBJECT
public:explicit JsonFormatter(QWidget *parent = nullptr) : QWidget(parent) {auto *layout = new QVBoxLayout(this);inputTextEdit = new QTextEdit(this);layout->addWidget(inputTextEdit);formatButton = new QPushButton("格式化", this);connect(formatButton, &QPushButton::clicked, this, &JsonFormatter::formatJson);layout->addWidget(formatButton);outputTextEdit = new QTextEdit(this);outputTextEdit->setReadOnly(true);layout->addWidget(outputTextEdit);setLayout(layout);}private slots:void formatJson() {QString inputText = inputTextEdit->toPlainText();QJsonParseError error{};QJsonDocument jsonDoc = QJsonDocument::fromJson(inputText.toUtf8(), &error);if (error.error != QJsonParseError::NoError) {outputTextEdit->setText("JSON 解析错误:" + error.errorString());return;}QJsonObject jsonObj = jsonDoc.object();QJsonDocument formattedJson(jsonObj);outputTextEdit->setText(formattedJson.toJson());}private:QTextEdit *inputTextEdit;QPushButton *formatButton;QTextEdit *outputTextEdit;
};class ClipboardManager : public QWidget {
Q_OBJECT
public:explicit ClipboardManager(QWidget *parent = nullptr) : QWidget(parent) {auto *layout = new QVBoxLayout(this);listWidget = new QListWidget(this);updateList(); // 初始更新列表auto *clearButton = new QPushButton("清空记录", this);connect(clearButton, &QPushButton::clicked, this, &ClipboardManager::clearClipboard);layout->addWidget(listWidget);layout->addWidget(clearButton);setLayout(layout);connect(myApp->clipboard(), &QClipboard::dataChanged, this, &ClipboardManager::updateList);}private slots:void updateList() {const QClipboard *clipboard = myApp->clipboard();const QMimeData *mimeData = clipboard->mimeData();if (mimeData->hasText()) {const QString clipboardText = mimeData->text();if (!clipboardText.isEmpty()) {listWidget->addItem(clipboardText);}}}void clearClipboard() {myApp->clipboard()->clear();listWidget->clear();}private:QListWidget *listWidget;
};class MyMainWindow : public QWidget {
Q_OBJECT
public:explicit MyMainWindow(QWidget *parent = nullptr) : QWidget(parent) {setWindowTitle("天河工具箱");auto *layout = new QVBoxLayout(this);auto *clipboardButton = new QPushButton("显示管理粘贴板记录功能");clipboardButton->setObjectName("clipboardButton");connect(clipboardButton, &QPushButton::clicked, this, &MyMainWindow::toggleClipboardManager);clipboardManager = new ClipboardManager(this);clipboardManager->hide();layout->addWidget(clipboardManager);layout->addWidget(clipboardButton);auto *jsonFormatButton = new QPushButton("显示格式化 JSON 功能");jsonFormatButton->setObjectName("jsonFormatButton");connect(jsonFormatButton, &QPushButton::clicked, this, &MyMainWindow::toggleJsonFormatter);jsonFormatter = new JsonFormatter(this);jsonFormatter->hide();layout->addWidget(jsonFormatter);layout->addWidget(jsonFormatButton);auto *timestampConverterButton = new QPushButton("显示时间戳转换功能");timestampConverterButton->setObjectName("timestampConverterButton");connect(timestampConverterButton, &QPushButton::clicked, this, &MyMainWindow::toggleDateTimeTimestampConverter);timestampConverter = new DateTimeTimestampConverter(this);timestampConverter->hide();layout->addWidget(timestampConverter);layout->addWidget(timestampConverterButton);auto *numberBaseConverterButton = new QPushButton("显示进制转换功能");numberBaseConverterButton->setObjectName("numberBaseConverterButton");connect(numberBaseConverterButton, &QPushButton::clicked, this, &MyMainWindow::toggleNumberBaseConverter);numberBaseConverter = new NumberBaseConverter(this);numberBaseConverter->hide();layout->addWidget(numberBaseConverter);layout->addWidget(numberBaseConverterButton);auto *xmlFormatterButton = new QPushButton("显示XML格式化功能");xmlFormatterButton->setObjectName("xmlFormatterButton");connect(xmlFormatterButton, &QPushButton::clicked, this, &MyMainWindow::toggleXmlFormatter);xmlFormatter = new XmlFormatter(this);xmlFormatter->hide();layout->addWidget(xmlFormatter);layout->addWidget(xmlFormatterButton);setLayout(layout);}private slots:void toggleClipboardManager() {auto* curButton = findChild<QPushButton*>("clipboardButton");if (clipboardManager->isHidden()) {if (curButton) {curButton->setText("隐藏管理粘贴板记录");}clipboardManager->show();} else {if (curButton) {curButton->setText("显示管理粘贴板记录");}clipboardManager->hide();}}void toggleJsonFormatter() {auto* curButton = findChild<QPushButton*>("jsonFormatButton");if (jsonFormatter->isHidden()) {if (curButton) {curButton->setText("隐藏格式化 JSON");}jsonFormatter->show();} else {if (curButton) {curButton->setText("显示格式化 JSON");}jsonFormatter->hide();}}void toggleDateTimeTimestampConverter() {auto* curButton = findChild<QPushButton*>("timestampConverterButton");if (timestampConverter->isHidden()) {if (curButton) {curButton->setText("隐藏时间戳转换");}timestampConverter->show();} else {if (curButton) {curButton->setText("显示时间戳转换");}timestampConverter->hide();}}void toggleNumberBaseConverter() {auto* curButton = findChild<QPushButton*>("numberBaseConverterButton");if (numberBaseConverter->isHidden()) {if (curButton) {curButton->setText("隐藏进制转换器");}numberBaseConverter->show();} else {if (curButton) {curButton->setText("显示进制转换器");}numberBaseConverter->hide();}}void toggleXmlFormatter() {auto* curButton = findChild<QPushButton*>("xmlFormatterButton");if (xmlFormatter->isHidden()) {if (curButton) {curButton->setText("隐藏XML格式化");}xmlFormatter->show();} else {if (curButton) {curButton->setText("显示XML格式化");}xmlFormatter->hide();}}private:ClipboardManager *clipboardManager;JsonFormatter *jsonFormatter;DateTimeTimestampConverter *timestampConverter;NumberBaseConverter *numberBaseConverter;XmlFormatter *xmlFormatter;
};int main(int argc, char *argv[]) {QApplication a(argc, argv);MyMainWindow mainWindow;mainWindow.show();return QApplication::exec();
}#include "main.moc"

经过这十二篇的文章讲解,我们的工具箱也逐渐成型了,看起来也像那么回事了。😁 后续我们继续为这个工具箱添砖加瓦,然后再粉饰粉饰界面,它就能出去见人了~

往期文章一览

C++学习之路(一)什么是C++?如何循序渐进的学习C++?【纯干货】

C++学习之路(二)C++如何实现一个超简单的学生信息管理系统?C++示例和小项目实例

C++学习之路(三)解析讲解超简单学生信息管理系统代码知识点 - 《根据实例学知识》

C++学习之路(四)C++ 实现简单的待办事项列表命令行应用 - 示例代码拆分讲解

C++学习之路(五)C++ 实现简单的文件管理系统命令行应用 - 示例代码拆分讲解

C++学习之路(六)C++ 实现简单的工具箱系统命令行应用 - 示例代码拆分讲解

C++学习之路(七)C++ 实现简单的Qt界面(消息弹框、按钮点击事件监听)- 示例代码拆分讲解

C++学习之路(八)C++ 用Qt5实现一个工具箱(增加一个粘贴板记录管理功能)- 示例代码拆分讲解

C++学习之路(九)C++ 用Qt5实现一个工具箱(增加一个JSON数据格式化功能)- 示例代码拆分讲解

C++学习之路(十)C++ 用Qt5实现一个工具箱(增加一个时间戳转换功能)- 示例代码拆分讲解

C++学习之路(十一)C++ 用Qt5实现一个工具箱(增加一个进制转换器功能)- 示例代码拆分讲解


好了~ 本文就到这里了,感谢您的阅读,每天还有更多的实例学习文章等着你 🎆。别忘了点赞、收藏~ Thanks♪(・ω・)ノ 🍇。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/232143.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ESP32-Web-Server 实战编程- 使用 AJAX 自动更新网页内容

ESP32-Web-Server 实战编程- 使用 AJAX 自动更新网页内容 概述 什么是 AJAX &#xff1f; AJAX Asynchronous JavaScript and XML&#xff08;异步的 JavaScript 和 XML&#xff09;。 AJAX 是一种用于创建快速动态网页的技术。 传统的网页&#xff08;不使用 AJAX&#…

【动态规划】LeetCode2552:优化了6版的1324模式

本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 动态规划 本题其它解法 C前缀和算法的应用&#xff1a;统计上升四元组 类似题解法 包括题目及代码C二分查找算法&#xff1a;132 模式解法一枚举3C二分查找算法&am…

二叉树(判断是否为对称二叉树)

题目&#xff08;力扣&#xff09;&#xff1a; 观察题目&#xff0c;只需判断该二叉树是否对称。 判断二叉树是否对称&#xff0c;就可以换位去判断该二叉树的左子树和右子树是否对称。 这时就可以写一个辅助函数来方便判断。 该函数是判断两颗树是否镜像对称&#xff0c;这…

AppDelete 4.3.3(软件清理卸载工具)

AppDelete for Mac是一款运行在Mac平台上的强大软件卸载工具&#xff0c;AppDelete Mac版不仅可以删除应用程序&#xff0c;还可以删除小部件&#xff0c;首选项窗格&#xff0c;插件和屏幕保护程序及其相关文件&#xff0c;卸载快速又干净&#xff0c;仅需要简单的拖拽即可。 …

Swift 常用关键字

目录 一、数据类型 1. 流程控制 2. 访问控制 3. 功能修饰词 4. 错误处理 5. 泛型和类型 6. 其它关键字 二、部分关键字说明 1. guard 2. class 和 struct struct&#xff08;结构体&#xff09; class&#xff08;类&#xff09; 使用场景 3. mutating 4. proto…

基于Netty实现TCP通信

创建一个Maven项目添加下面依赖 <dependencies><!-- 日志依赖 --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.32</version></dependency><dependency><g…

LeetCode刷题---斐波那契数列模型

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C/C》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、第N个泰波那契数 题目链接&#xff1a;1137. 第 N 个泰波那契数 题目描述 泰波那契序列Tn定义如下: T00,T11,T2 1,且在n&g…

SpringBoot项目发送邮件

&#x1f4d1;前言 本文主要是【SpringBoot】——SpringBoot项目发送邮件的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f3…

电子学会C/C++编程等级考试2021年03月(二级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:石头剪刀布 石头剪刀布是常见的猜拳游戏。石头胜剪刀,剪刀胜布,布胜石头。如果两个人出拳一样,则不分胜负。 一天,小A和小B正好在玩石头剪刀布。已知他们的出拳都是有周期性规律的,比如:“石头-布-石头-剪刀-石头-布-石头…

PTA-2023年软件设计综合实践_9(动态规划法)

7-1 数塔 数塔如图所示&#xff0c;若每一步只能走到相邻的结点&#xff08;图中有数字的方格&#xff09;&#xff0c;则从最顶层走到最底层所经过的所有结点的数字之和最大是多少&#xff1f;测试数据保证结果不大于231−1。 C #include <bits/stdc.h> using namespa…

pycharm怎么同时打开2个项目?

pycharm怎么同时打开2个项目&#xff1f;当使用vue等前端的时候&#xff0c;后台也需要同时用pycharm打开操作&#xff0c;怎么用pycharm同时打开前后端呢&#xff1f; 当我们第一次用pycharm的时候&#xff0c;新建一个项目&#xff0c;习惯选择此窗口&#xff0c;而且勾选不再…

金蝶云星空的BOS套打设计器的入口

文章目录 登录业务账套套打设计器界面 登录业务账套 个人信息-下载中心-BOS套打设计器 套打设计器界面