【结对项目】单词计数WordCount代码
程序员文章站
2022-05-04 17:30:48
...
单词计数代码实现
具体思路和说明见前一篇博客。
头文件:
stdafx.h:
/*
* stdafx.h : 文件调用
*/
//#pragma once
#include <stdio.h>
#include <string.h>
#include <string>
#include <stdlib.h>
#include <io.h>
#include <windows.h>
#include <tchar.h>
#include <atlstr.h>
using namespace std;
#include "define.h"
#include "fundamental.h"
#include "extended.h"
#define MAXLEN 100005 // 输入路径的最长长度
//#pragma warning(disable:4996)
主函数(对外窗口):
main.cpp:
主要实现从命令行读入指令,然后判断输入是否正确,正确则执行指令。
/*
* Project: WordCount
* Function:
* 1.实现统计文件的字符数、单词数、行数
* 2.实现递归处理目录下符合条件的文件
* 3.实现图形界面功能
* Author: 李林峰, 马伯乐
* Student Number: 1120161918, 1120161922
* Version: 6.2
* Date: May 12,2018
*/
//#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
int main(int argc, char* argv[])
{
if (strcmp(argv[1], "-s") == 0) { // 递归处理目录下符合条件的文件
TCHAR szPath[MAX_PATH] = { 0 };
if (GetModuleFileName(NULL, szPath, MAX_PATH)) {
(_tcsrchr(szPath, _T('\\')))[1] = 0;
}
string Path;
Wchar_tToString(Path, szPath);
for (int i = 0; i < argc; i++)
strcpy(para[i], argv[i]);
search_file(Path, argc - 1);
}
else if (strcmp(argv[1], "-x") == 0) { // 高级功能: 图形界面
ShellExecuteA(NULL, "open", "WordCount.exe", NULL, NULL, SW_SHOW);
}
else { // 对单个.c文件的统计
int num_para;
for (num_para = argc - 1; num_para > 1; num_para--) {
if ( strcmp(argv[num_para], "-s") == 0 || strcmp(argv[num_para], "-x") == 0
|| strcmp(argv[num_para], "-c") == 0 || strcmp(argv[num_para], "-w") == 0
|| strcmp(argv[num_para], "-l") == 0 || strcmp(argv[num_para], "-a") == 0 )
{break;}
}
char filename[500] = {0};
strcat(filename, argv[num_para+1]);
for (int i = num_para+2;i < argc;i++) {
strcat(filename, " ");
strcat(filename, argv[i]);
}
int flag_3 = check_file_name(filename);
if (flag_3 == -1) {
printf("Wrong: File does not exist !\n");
return 0;
}
else if (flag_3 == -2) {
printf("Wrong: File has no read permissions !\n");
return 0;
}
printf("%s:\n", filename);
for (int i = 1; i <= num_para; i++) {
if (check_order(argv[i]) == 1)
basic_command(argv[i], filename);
else
printf("Wrong: Command parameter error !\n");
}
}
return 0;
}
基本输入输出检查模块:
define.h
#ifndef __DIFINE_H__
#define __DIFINE_H__
// 全局变量声明: 命令参数
extern char para[200][500];
// 函数声明: 检查文件是否存在并可以读取
int check_file_name(char filename[]);
// 函数声明: 检查命令是否正确
int check_order(char order[]);
// 函数声明: 单条基本命令的处理
void basic_command(char order[], char filename[]);
#endif
define.cpp
/*
* 本文件实现基本输入输出检查
*/
#include "stdafx.h"
/// 用于复制命令参数
char para[200][500];
/// <summary> 检查文件是否存在并可以读取 </summary>
/// <param name="filename"> 文件名称 </param>
/// <return>
/// -1: 文件不存在
/// -2: 文件存在但没有读取权限
/// 1: 文件有访问权限
/// </return>
int check_file_name(char filename[])
{
if (access(filename, 0) != 0) { return -1; } // 文件不存在返回-1
if (access(filename, 4) != 0) { return -2; } // 文件不能读取返回-2
return 1;
}
/// <summary> 检查命令是否正确 </summary>
/// <param name="order"> 命令名称 </param>
/// <return> -1: 命令格式错误; 1: 正确的命令格式 </return>
int check_order(char order[])
{
int len = strlen(order);
if (len != 2 || order[0] != '-') return -1;
if (order[1] == 'c' || order[1] == 'w' || order[1] == 'l' || order[1] == 'a') {
return 1;
}
else return -1;
}
/// <summary> 单条基本命令的处理 </summary>
void basic_command(char order[], char filename[])
{
switch (order[1]) {
case 'c':
printf(" The number of characters: %d\n", count_character(filename));
break;
case 'w':
printf(" The number of words: %d\n", count_word(filename));
break;
case 'l':
printf(" The number of lines: %d\n", count_line(filename));
break;
case 'a':
complex_data_statistics(filename);
break;
}
}
基本功能模块
fundamental.h
#ifndef __FUNDAMENTAL_H__
#define __FUNDAMENTAL_H__
// 函数声明: 输出文件字符数
int count_character(char file[]);
// 函数声明: 输出文件单词数
int count_word(char file[]);
// 函数声明: 输出文件行数
int count_line(char file[]);
#endif
fundamental.cpp
/*
* 本文件实现基本功能
*/
#include "stdafx.h"
/// <summary> 输出文件字符数 </summary>
int count_character(char file[])
{
int ch_num = 0;
char ch;
freopen(file, "r", stdin);
while ((ch = getchar()) != EOF) {
if (ch != ' '&&ch != '\n'&&ch != '\t')
ch_num++;
}
fclose(stdin);
return ch_num;
}
/// <summary> 输出文件单词数 </summary>
int count_word(char file[])
{
int w_num = 0, is_word = 0;
char ch;
freopen(file, "r", stdin);
while ((ch = getchar()) != EOF) {
if ((ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z') || ch == '_')
is_word = 1;
else {
if (is_word) {
w_num++;
is_word = 0;
}
}
}
fclose(stdin);
return w_num;
}
/// <summary> 输出文件行数 </summary>
int count_line(char file[])
{
int l_num = 0;
char ch;
freopen(file, "r", stdin);
while ((ch = getchar()) != EOF) {
if (ch == '\n')
l_num++;
}
fclose(stdin);
return l_num;
}
拓展功能模块
extended.h
#ifndef __EXTENDED_H__
#define __EXTENDED_H__
#include "stdafx.h"
// 函数声明: 复杂数据统计
void complex_data_statistics(char file[]);
// 函数声明: 统计文件 空行 数
int count_blankline(char file[]);
// 函数声明: 统计文件注释行数
int count_noteline(char file[]);
// 函数声明: 统计文件代码行数
int count_codeline(char file[]);
// 函数声明:递归搜索目录
void search_file(string path, int idx);
// 函数声明:Wchar to string
void Wchar_tToString(string& szDst, wchar_t *wchar);
#endif
extended.cpp
/*
* 本文件实现扩展功能
*/
#include "stdafx.h"
/// <summary> 复杂数据统计 </summary>
void complex_data_statistics(char file[])
{
int b_num = count_blankline(file); // 空行数
int n_num = count_noteline(file); // 注释行数
int cl_num = count_line(file) - b_num - n_num; // 代码行数
printf(" The number of code lines: %d\n", cl_num);
printf(" The number of blank lines: %d\n", b_num);
printf(" The number of note lines: %d\n", n_num);
}
/// <summary> 统计文件 空行 数 </summary>
int count_blankline(char file[])
{
int b_num = 0, ch_num = 0;
char ch;
freopen(file, "r", stdin);
while ((ch = getchar()) != EOF) {
if (ch == '\n'){
if (ch_num <= 1)
b_num++;
ch_num = 0;
}
else if (ch != ' '&&ch != '\t')
ch_num++;
}
fclose(stdin);
return b_num;
}
/// <summary> 统计文件注释行数 </summary>
int count_noteline(char file[])
{
int n_num = 0, line = 0, ch_num = 0, flag_1 = 0, flag_2 = 0, flag_3 = 0, thisline = 0;
char ch;
freopen(file, "r", stdin);
while ((ch = getchar()) != EOF) {
if (ch == '\n'){
if (line&&ch_num > 0)
line++;
ch_num = 0;
flag_1 = thisline = 0;
}
if (thisline == 1)
continue;
if (ch != ' '&&ch != '\t'&&ch != '\n')
ch_num++;
if (flag_2){
if (ch != ' '&&ch != '\t'&&ch != '\n')
ch_num++;
if (ch == '*')
flag_3 = 1;
else if (ch == '/'&&flag_3){
n_num += line;
line = 0;
flag_2 = flag_3 = 0;
thisline = 1;
}
else
flag_3 = 0;
}
else if (ch == '/') {
if (flag_1 == 0)
flag_1 = 1;
else if (flag_1 == 1 && ch_num <= 3){
n_num++;
thisline = 1;
}
}
else if (ch == '*'){
if (flag_1 == 1){
flag_2 = 1;
line = 1;
}
}
else
flag_1 = 0;
}
fclose(stdin);
return n_num;
}
/// <summary> 统计文件代码行数 </summary>
int count_codeline(char file[])
{
int line = count_line(file);
int blank = count_blankline(file);
int note = count_noteline(file);
int cl_num = line - blank - note;
return cl_num;
}
/// <summary> wchar_t to string </summary>
void Wchar_tToString(std::string& szDst, wchar_t *wchar)
{
wchar_t * wText = wchar;
DWORD dwNum = WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, NULL, 0, NULL, FALSE);
char *psText;
psText = new char[dwNum];
WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, psText, dwNum, NULL, FALSE);
szDst = psText;
delete[]psText;
}
/// <summary> 递归处理文件 </summary>
void search_file(string path, int idx)
{
struct _finddata_t filefind;
string cur = path + "*.*";
int done = 0, handle;
if ((handle = _findfirst(cur.c_str(), &filefind)) != -1) {
while (!(done = _findnext(handle, &filefind))) {
if (strcmp(filefind.name, "..") == 0)
continue;
if ((_A_SUBDIR == filefind.attrib)) { //目录
cur = path + filefind.name + '\\';
search_file(cur, idx); //递归处理
}
else {
int len = strlen(filefind.name);
for (int i = 0; i < len; i++) {
if (filefind.name[i] == '.') {
len = i;
break;
}
}
if (strcmp(filefind.name + len, para[idx] + 1) == 0) {
cur = path + filefind.name;
printf("%s:\n", filefind.name);
for (int i = 1; i < idx; i++)
basic_command(para[i], &cur[0]);
}
}
}
_findclose(handle);
}
}
高级功能模块
本部分实现界面功能,使用C#完成
WordCount.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace InterFace
{
public partial class WordCount : Form
{
public WordCount()
{
InitializeComponent();
}
public void ProcessOutDataReceived(object sender, DataReceivedEventArgs e)
{
if (this.txtOutPutInfo.InvokeRequired)
{
this.txtOutPutInfo.Invoke(new Action(() =>
{
this.txtOutPutInfo.AppendText(e.Data + "\r\n");
}));
}
else
{
this.txtOutPutInfo.AppendText(e.Data + "\r\n");
}
}
public bool StartProcess(string filename, string[] args)
{
try
{
string s = "";
foreach (string arg in args)
{
s = s + arg + " ";
}
s = s.Trim();
Process myprocess = new Process();
myprocess.OutputDataReceived -= new DataReceivedEventHandler(ProcessOutDataReceived);
ProcessStartInfo startInfo = new ProcessStartInfo(filename, s);
startInfo.FileName = "wc.exe";
startInfo.UseShellExecute = false;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
myprocess.StartInfo = startInfo;
myprocess.StartInfo.UseShellExecute = false;
myprocess.Start();
myprocess.BeginOutputReadLine();
myprocess.OutputDataReceived += new DataReceivedEventHandler(ProcessOutDataReceived);
return true;
}
catch (Exception ex)
{
MessageBox.Show("启动应用程序时出错!原因:" + ex.Message);
}
return false;
}
private void view_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog(); //显示选择文件对话框
openFileDialog1.InitialDirectory = "c:\\";
openFileDialog1.Filter = "All files (*.*)|*.*";
openFileDialog1.FilterIndex = 2;
openFileDialog1.RestoreDirectory = true;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
this.txtFilepath.Text = openFileDialog1.FileName; //显示文件路径
}
}
private void count_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(this.txtFilepath.Text.Trim()))
{
MessageBox.Show("请选择文件");
}
string[] arg = new string[10];
arg[0] = "-c"; arg[1] = "-w"; arg[2] = "-l"; arg[3] = "-a";
arg[4] = this.txtFilepath.Text.Trim();
StartProcess(@"wc.exe", arg);
}
private void path_Click(object sender, EventArgs e)
{
}
}
}
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace InterFace
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new WordCount());
}
}
}
WordCount.Designer.cs
namespace InterFace
{
partial class WordCount
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WordCount));
this.count = new System.Windows.Forms.Button();
this.view = new System.Windows.Forms.Button();
this.txtFilepath = new System.Windows.Forms.TextBox();
this.txtOutPutInfo = new System.Windows.Forms.TextBox();
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
this.path = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// count
//
this.count.Font = new System.Drawing.Font("幼圆", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.count.Location = new System.Drawing.Point(31, 232);
this.count.Name = "count";
this.count.Size = new System.Drawing.Size(752, 27);
this.count.TabIndex = 0;
this.count.Text = "统 计";
this.count.UseVisualStyleBackColor = true;
this.count.Click += new System.EventHandler(this.count_Click);
//
// view
//
this.view.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))));
this.view.Font = new System.Drawing.Font("华文新魏", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.view.Location = new System.Drawing.Point(656, 193);
this.view.Name = "view";
this.view.Size = new System.Drawing.Size(127, 27);
this.view.TabIndex = 1;
this.view.Text = "浏览";
this.view.UseVisualStyleBackColor = false;
this.view.Click += new System.EventHandler(this.view_Click);
//
// txtFilepath
//
this.txtFilepath.Font = new System.Drawing.Font("宋体", 9F);
this.txtFilepath.Location = new System.Drawing.Point(105, 196);
this.txtFilepath.Name = "txtFilepath";
this.txtFilepath.Size = new System.Drawing.Size(522, 21);
this.txtFilepath.TabIndex = 2;
//
// txtOutPutInfo
//
this.txtOutPutInfo.Font = new System.Drawing.Font("宋体", 9F);
this.txtOutPutInfo.Location = new System.Drawing.Point(31, 269);
this.txtOutPutInfo.Multiline = true;
this.txtOutPutInfo.Name = "txtOutPutInfo";
this.txtOutPutInfo.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.txtOutPutInfo.Size = new System.Drawing.Size(752, 161);
this.txtOutPutInfo.TabIndex = 3;
//
// openFileDialog1
//
this.openFileDialog1.FileName = "openFileDialog1";
//
// path
//
this.path.AutoSize = true;
this.path.BackColor = System.Drawing.Color.Transparent;
this.path.Font = new System.Drawing.Font("幼圆", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.path.Location = new System.Drawing.Point(29, 199);
this.path.Name = "path";
this.path.Size = new System.Drawing.Size(75, 15);
this.path.TabIndex = 4;
this.path.Text = "文件路径";
this.path.Click += new System.EventHandler(this.path_Click);
//
// WordCount
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackgroundImage = global::InterFace.Properties.Resources.bg___1;
this.ClientSize = new System.Drawing.Size(813, 479);
this.Controls.Add(this.path);
this.Controls.Add(this.txtOutPutInfo);
this.Controls.Add(this.txtFilepath);
this.Controls.Add(this.view);
this.Controls.Add(this.count);
this.Font = new System.Drawing.Font("宋体", 10F);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "WordCount";
this.Text = "WordCount";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button count;
private System.Windows.Forms.Button view;
private System.Windows.Forms.TextBox txtFilepath;
private System.Windows.Forms.TextBox txtOutPutInfo;
private System.Windows.Forms.OpenFileDialog openFileDialog1;
private System.Windows.Forms.Label path;
}
}