首页 > 编程语言 >C++实现命令行文本计数统计程序

C++实现命令行文本计数统计程序

时间:2024-11-10 20:14:58浏览次数:5  
标签:命令行 number C++ 计数 long file txt infile string

附上一位博主写的关于git的使用(个人感觉非常完整,对新手很友好):Git及Tortoisegit下载安装及使用详细配置过程_tortoisegit下载远程代码-CSDN博客
 Gitee地址 :https://gitee.com/wnmdsqwnhkmc/second-assignment

注:本文并不包含主函数,完整代码请移步Gitee
路径:[项目>>ConsoleApplication1>>(无前缀)ConsoleApplication1>>ConsoleApplication1.cpp]


一、项目的简介及其相关的用法

(一)项目介绍


该项目旨在实现一个命令行文本计数统计程序。
基础功能:能正确统计导入的纯英文txt文本中的字符数,单词数,句子数。
拓展功能:能正确统计导入的txt文本中的代码行,空白行,注释行。
具体命令行界面要求举例:

命令模式: wc.exe + [参数] [文件名]

以下为示例:
1. wc.exe -c file.txt 统计字符数
2. wc.exe -w file.txt 统计单词数
3. wc.exe -s file.txt 统计句子数
4. wc.exe -code file.txt 统计代码行
5. wc.exe -e file.txt 统计空白行
6. wc.exe -n file.txt 统计注释行

其中,"wc"为应用程序的名称,"-c""-w""-s"等为命令参数,"file"为txt文件的名称。

(二)具体操作


1. win+r,输入cmd

2. 输入应用程序exe文件所在位置(本程序位于D盘的“测试”文件夹中,注意cd后需有空格)

3. 输入示例命令"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"

五、最后附上单元测试完整代码

#include <string>
#include <iostream>
#include <fstream>
#include <cassert>
#include <chrono>
using namespace std;

// 显示帮助信息  
void help() {
    cout << "Usage: " << endl;
    cout << "-c : 统计字符数" << endl;
    cout << "-w : 统计单词书" << endl;
    cout << "-s : 统计句子数" << endl;
    cout << "-code : 统计代码数" << endl;
    cout << "-e : 统计空行数" << endl;
    cout << "-n : 统计注释数" << endl;
    cout << "-h : 显示帮助" << endl;
}


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;
}

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 countEmpty(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";
}

int main(int argc, char* argv[]) {
    cout << "-------------------单元测试部分--------------------" << endl;
    run_tests();
    cout << "-------------------------------------------------" << endl;
    cout << "\n\n-------------------性能测试部分--------------------" << endl;
    performance_test();
    cout << "-------------------------------------------------" << endl;
    cout << "\n\n-------------------程序功能部分------------------" << endl;
    string c = "-c", w = "-w", s = "-s", code = "-code", e = "-e", n = "-n", h = "-h";
    if (argc < 2) {
        help();
        return 0;
    }

    string option = argv[1];
    string filename = (argc > 2) ? argv[2] : "";

    if (option == h) {
        help();
    }
    else if (option == c) {
        cout << count(filename) << " 字符数" << endl;
    }
    else if (option == w) {
        cout << word(filename) << " 单词数" << endl;
    }
    else if (option == s) {
        cout << sentence(filename) << " 句子数" << endl;
    }
    else if (option == code) {
        cout << cod(filename) << " 代码数" << endl;
    }
    else if (option == e) {
        cout << countEmpty(filename) << " 空行数" << endl;
    }
    else if (option == n) {
        cout << note(filename) << " 注释行数" << endl;
    }
    else {
        cout << "Unknown option: " << option << endl;
        help();
    }
    return 0;
}

标签:命令行,number,C++,计数,long,file,txt,infile,string
From: https://blog.csdn.net/weixin_73643464/article/details/143665047

相关文章

  • C++中的RAII与内存管理
    C++中的RAII与内存管理引言资源获取即初始化(ResourceAcquisitionIsInitialization,简称RAII)是C++编程中一种重要的编程范式,它通过对象生命周期来管理资源,确保资源在不再需要时能够被正确释放。本文将从C++的内存布局入手,逐步深入到栈区、堆区的概念,new和delete的操作原理,最终......
  • 浅谈C++(2)
    hi,大家好,我们又见面了今天我继续来讲C++2:变量变量是什么?变量像一个盒子,里面的内容是可以更改的变量的定义:inta;如上代码段,是定义了一个为整数类型的变量a你可以使用cin>>a;来使它变成另一个值解释int是一种变量类型,只储存整数a是变量名;分号,分隔每一......
  • 找质数程序C++
    找质数程序C++今天看报纸时看到目前算出来最大的质数是2136279841-1于是自编了一串代码,分享给大家(ps:怕电脑冒烟的慎用)#include<iostream>usingnamespacestd;intmain(){ for(longlongi=9574463;;i+=2){ if(i%2!=0&&i%3!=0&&i%5!=0&&i%7!=0&&i%......
  • c++程序设计基础实验三
    任务1:源代码:button.hpp:#pragmaonce#include<iostream>#include<string>usingstd::string;usingstd::cout;//按钮类classButton{public:Button(conststring&text);stringget_label()const;voidclick();priva......
  • C++17 多态内存管理 pmr
    C++17多态内存管理pmr概念C++17开始,增加特性PolymorphicMemoryResources多态内存资源,缩写PMR。提供新的内存分配策略,更灵活地控制内存的分配与回收——适用于嵌入式和高并发服务器场景。对内存资源的抽象抽象基类std::pmr::memory_resource定义了用于内存的分......
  • C++STL容器适配器——stack和queue
    目录一.stack介绍及使用1.stack介绍2.stack的使用3.模拟实现stack二.queue的介绍及使用1.queue介绍2.queue的使用3.模拟实现queue三.deque的了解1.deque的介绍2.deque的缺陷四.priority_queue的介绍及使用1.priority_queue介绍2.priority_queue的使用3.模拟实......
  • C/C++语言基础--C++模板与元编程系列五(可变惨模板,形参包展开,折叠表达式)
    本专栏目的更新C/C++的基础语法,包括C++的一些新特性前言模板与元编程是C++的重要特点,也是难点,本人预计将会更新10期左右进行讲解,这是第五期,讲解可变惨模板,形参包展开,折叠表达式等,本人感觉这一部分内容还是比较复杂的;C语言后面也会继续更新知识点,如内联汇编;欢迎收藏+关......
  • 【最新原创毕设】基于移动端的助农电商系统+08655(免费领源码)可做计算机毕业设计JAVA、
    基于移动端的助农电商系统的设计与实现摘要近年来,电子商务的快速发展引起了行业和学术界的高度关注。基于移动端的助农电商系统旨在为用户提供一个简单、高效、便捷的农产品购物体验,它不仅要求用户清晰地查看所需信息,而且还要求界面设计精美,使得功能与页面完美融合,从而提升......
  • (2024最新毕设合集)基于SpringBoot的梓锦社区疫苗接种服务系统+42529|可做计算机毕业设
    目 录摘要1绪论1.1选题背景与意义1.2开发现状1.3论文结构与章节安排2 梓锦社区疫苗接种服务系统系统分析2.1可行性分析2.1.1技术可行性分析2.1.2 经济可行性分析2.1.3法律可行性分析2.2系统功能分析2.2.1功能性分析2.2.2非功能性分析2.......
  • 封装红黑树实现mymap和myset--C++
    源码及框架分析SGI-STL30版本源代码,map和set的源代码在map/set/stl_map.h/stl_set.h/stl_tree.h等几个头文件中。map和set的实现结构框架核心部分截取出来如下://set#ifndef__SGI_STL_INTERNAL_TREE_H#include<stl_tree.h>#endif#include<stl_set.h>#include<st......