第二次作业
这个作业属于哪个课程 | https://edu.cnblogs.com/campus/zjlg/rjjc |
---|---|
这个作业的目标 | 实现一个命令行文本计数统计程序。能正确统计导入的纯英文txt文本中的字符数,单词数,句子数 |
姓名-学号 | 吴誉斐-2022329301102 |
Gitee地址 | https://gitee.com/wnmdsqwnhkmc/second-assignment.git |
注:本文并不包含主函数,完整代码请移步Gitee
路径:[项目>>ConsoleApplication1>>(无前缀)ConsoleApplication1>>ConsoleApplication1.cpp]
一、项目的简介及其相关的用法
(一)项目介绍
该项目旨在实现一个命令行文本计数统计程序。
基础功能:能正确统计导入的纯英文txt文本中的字符数,单词数,句子数。
拓展功能:能正确统计导入的txt文本中的代码行,空白行,注释行。
具体命令行界面要求举例:
命令模式: wc.exe + [参数] [文件名]
以下为示例:
- wc.exe -c file.txt 统计字符数
- wc.exe -w file.txt 统计单词数
- wc.exe -s file.txt 统计句子数
- wc.exe -code file.txt 统计代码行
- wc.exe -e file.txt 统计空白行
- wc.exe -n file.txt 统计注释行
其中,"wc"为应用程序的名称,"-c""-w""-s"等为命令参数,"file"为txt文件的名称。
(二)具体操作
- win+r,输入cmd
- 输入应用程序exe文件所在位置(本程序位于D盘的“测试”文件夹中,注意cd后需有空格)
- 输入示例命令"ConsoleApplication1.exe -c word.txt"。该处程序名为"ConsoleApplication1",txt文件名为word。
二、文件列表及其相关说明
(一)v0.1 空项目:该项目为C++读取文本文件的简单测试。
#include <iostream>
#include <fstream> // 包含用于文件输入输出的头文件
#include <string>
using namespace std;
int main() {
string path = "./word.txt";
// 直接在构造函数中打开文件
ifstream in_file(path);
// 检查文件是否成功打开
if (in_file) {
cout << "Open File Successfully" << endl;
string line;
// 逐行读取文件内容并打印到控制台
while (getline(in_file, line)) {
cout << line << endl;
}
}
else {
// 使用cerr进行错误输出
cerr << "Cannot Open File: " << path << endl;
return EXIT_FAILURE; // 直接返回失败状态
}
return EXIT_SUCCESS; // 返回成功状态
}
(二)v0.2 项目完成基础功能:该项目可实现对txt文件的读取操作,并对其中字符数,单词数,句子数进行统计。
- 统计字符数
//在本项目中,字符数包括标点、空格、字母
long count(string file) {
char c;
long number = 0;
ifstream infile(file);
assert(infile.is_open());
while (infile.get(c)) {
number++;
}
infile.close();
return number;
}
- 统计单词数
long word(string file) {
char c;
long number = 0;
bool inWord = false;
ifstream infile(file);
assert(infile.is_open());
infile >> noskipws;
while (infile.get(c)) {
if (isalpha(c)) {
if (!inWord) {
inWord = true;
number++;
}
}
else {
inWord = false;
}
}
infile.close();
return number;
}
- 统计句子数
long sentence(string file) {
char c;
long number = 0;
bool inSentence = false;
ifstream infile(file);
assert(infile.is_open());
infile >> noskipws;
while (infile.get(c)) {
if (isalpha(c) || isdigit(c)) {
if (!inSentence) {
inSentence = true;
}
}
else if (c == '.' || c == ';') {
if (inSentence) {
number++;
inSentence = false;
}
}
else {
inSentence = false;
}
}
// 判断最后一个字符是不是句子的一部分
if (inSentence) number++;
infile.close();
return number;
}
(三)v0.3 项目完成扩展功能:实现统计代码行、空行、注释行等操作。
- 统计代码行
long cod(string file) {
long number = 0;
ifstream infile(file);
assert(infile.is_open());
string line;
while (getline(infile, line)) {
number++;
}
infile.close();
return number;
}
- 统计空行
long empty(string file) {
long number = 0;
ifstream infile(file);
assert(infile.is_open());
string line;
while (getline(infile, line)) {
if (line.empty()) {
number++;
}
}
infile.close();
return number;
}
- 统计注释行
long note(string file) {
char c;
long number = 0;
bool inComment = false;
ifstream infile(file);
assert(infile.is_open());
while (infile.get(c)) {
if (c == '/') {
char nextChar;
infile.get(nextChar);
if (nextChar == '/') {
inComment = true;
number++; // 用 '//' 判断一段注释行
break; // 只要检测到了,就可以停止这一行的检测
}
else {
infile.putback(nextChar);
}
}
else if (c == '\n') {
inComment = false;
}
}
infile.clear(); // 清除 EOF flag
infile.seekg(0, ios::beg);
string line;
while (getline(infile, line)) {
if (line.find("//") != string::npos) {
number++;
}
}
infile.close();
if (number > 0) number--;
return number;
}
(四)单元测试及性能测试
- 单元测试
void test_count() {
ofstream file("file1.txt");
file << "Hello, World!";
file.close();
assert(count("file1.txt") == 13);
}
void test_word() {
ofstream file("file2.txt");
file << "This is a test.";
file.close();
assert(word("file2.txt") == 4);
}
void test_sentence() {
ofstream file("file2.txt");
file << "This is a test. It works well;";
file.close();
assert(sentence("file2.txt") == 2);
}
void test_cod() {
ofstream file("file3.txt");
file << "int main() {\n";
file << " // this is a comment\n";
file << " return 0;\n";
file << "}\n\n";
file.close();
assert(cod("file3.txt") == 5);
}
void test_empty() {
ofstream file("file3.txt");
file << "int main() {\n";
file << "\n";
file << " return 0;\n";
file << "}\n\n";
file.close();
assert(countEmpty("file3.txt") == 2);
}
void test_note() {
ofstream file("file3.txt");
file << "// comment 1\n";
file << "int main() {\n";
file << " // comment 2\n";
file << " return 0;\n";
file << "}\n";
file.close();
assert(note("file3.txt") == 2);
}
void run_tests() {
test_count();
test_word();
test_sentence();
test_cod();
test_empty();
test_note();
cout << "所有单元测试通过!" << endl;
}
- 性能测试
void performance_test() {
ofstream file("large_file.txt");
for (int i = 0; i < 100000; i++) {
file << "This is line " << i << ". // Comment line\n";
file << "int value" << i << " = " << i << ";\n";
if (i % 10 == 0) {
file << "\n";
}
}
file.close();
auto start = chrono::high_resolution_clock::now();
cout << "字符数: " << count("large_file.txt") << endl;
auto end = chrono::high_resolution_clock::now();
cout << "字符统计用时: "
<< chrono::duration_cast<chrono::milliseconds>(end - start).count() << " ms\n";
start = chrono::high_resolution_clock::now();
cout << "单词数: " << word("large_file.txt") << endl;
end = chrono::high_resolution_clock::now();
cout << "单词统计用时: "
<< chrono::duration_cast<chrono::milliseconds>(end - start).count() << " ms\n";
start = chrono::high_resolution_clock::now();
cout << "句子数: " << sentence("large_file.txt") << endl;
end = chrono::high_resolution_clock::now();
cout << "句子统计用时: "
<< chrono::duration_cast<chrono::milliseconds>(end - start).count() << " ms\n";
start = chrono::high_resolution_clock::now();
cout << "代码行数: " << cod("large_file.txt") << endl;
end = chrono::high_resolution_clock::now();
cout << "代码统计用时: "
<< chrono::duration_cast<chrono::milliseconds>(end - start).count() << " ms\n";
start = chrono::high_resolution_clock::now();
cout << "空行数: " << countEmpty("large_file.txt") << endl;
end = chrono::high_resolution_clock::now();
cout << "空行统计用时: "
<< chrono::duration_cast<chrono::milliseconds>(end - start).count() << " ms\n";
start = chrono::high_resolution_clock::now();
cout << "注释行数: " << note("large_file.txt") << endl;
end = chrono::high_resolution_clock::now();
cout << "注释统计用时: "
<< chrono::duration_cast<chrono::milliseconds>(end - start).count() << " ms\n";
}
三、例程运行及其相关结果
(一)v0.1 空项目
(二)v0.2 项目完成基础功能
(三)v0.3 项目完成扩展功能
(四)单元测试与性能测试
- CPU使用率
四、心得感悟
- Git推送代码失败时,在Bash输入"git push -f origin master"
这次作业让我对C++编程语言及其相关拓展库有了深入的理解。在编写一个命令行文本计数统计程序的过程中,我掌握了处理文本文件的方法,并能够统计字符数、单词数、句子数,以及实现拓展功能。此外,我还了解了单元测试以及性能测试等相关知识,虽然不太会用,但也算拓宽了知识面,还从零学习使用Gitee,收获了很多。
PS:每次上传新代码,推送都会失败,然后库就清空了,然后readme也没了,然后gitee上显示的提交次数就很少。