个人项目——wc源程序特征统计

这一次要做的项目是wc——统计程序文件特征的命令行程序。

根据需求需求得到的模式为:wc.exe [parameter][filename]

在[parameter]中,用户通过输入参数与程序交互,需实现的功能如下:

1、基本功能

  • 支持 -c  统计文件字符数
  • 支持 -w 统计文件单词数
  • 支持 -l  统计文件总行数

2、拓展功能

  • 支持 -a 返回高级选项(代码行 空行 注释行)
  • 支持 -s 递归处理符合条件的文件

3、高级功能

  • 支持 -x 程序以图形界面与用户交互

[filename] 是待处理文件名。

 

最近在学习c#故而用c#实现本程序。

基本功能的实现:

 为实现程序能够实现-c、-l、-w对应的功能,我在新建的解决方案下又添加了一个count类,在这个类中有一个文件的基本信息:字符数、单词数、行数。这些信息都保存在字段中(c#中有get、set方法的才叫属性),之后根据快捷键ctr+r+e生成各种对应的属性;

之后就是关于信息的获取,

1、建立void infile(sFilename)方法,来进入文件,循环读取文件每一行的内容,内容保存字符串str中,之后将读取的每一行的内容以参数的形式进入,统计文件一行信息的方法void perLineWord(str);

2、建立void perLineWord(str)方法,根据读取的文件的一行信息进行统计;先用循环将传进来的str中开头的空格遍历出去,空格数对应的加1,一旦读到的不是空格跳出循环,判断是不是字母,如果是字母就进入字母、数字、下划线的循环中,如果都不是就跳出循环,之后单词数加1;再判断导致循环结束的是不是空格,若是空格数加1;一直将str字符串读完,结束。代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Diagnostics;
namespace count_wc
{
    class Count
    {
        int konggenum ;//空格及制表符
        int charnum;//字符数 = 总个数—空格、制表符数
        int wordsnum;
        int lines;
        string sFilename;

        public string SFilename
        {
            get { return sFilename; }
            set { sFilename = value; }
        }

        //属性
        public  int Konggenum
        {
            get { return konggenum; }
            set { konggenum = value; }
        }


        public  int Charnum
        {
            get { return charnum; }
            set { charnum = value; }
        }


        public int Wordsnum
        {
            get { return wordsnum; }
            set { wordsnum = value; }
        }


        public int Lines
        {
            get { return lines; }
            set { lines = value; }
        }


        public Count()
        {

             konggenum = 0;
             charnum = 0;
             wordsnum = 0;
             lines = 0;
        
        
        }

        /// <summary>
        /// 进入文件
        /// </summary>
        /// <param name="sFilename"></param>
         public void infile(string sFilename)
        {
            this.sFilename = sFilename;
            int length = 0;//总长度
            // count.RunCmd(@"C:\WINDOWS\system32\cmd.exe ","aa");

           try
           {
               
    //            FileStream file = new FileStream(sFilename, FileMode.Open, FileAccess.Read, FileShare.Read);
                    StreamReader sr = new StreamReader(sFilename, Encoding.Default);
                
                    string str;
                    while ((str = sr.ReadLine()) != null)
                    {
                        lines++;
                        perLineWord(str);

                        // perLineWord(str);                
                    }
                    sr.Close();
          }
          catch
          {
                    Console.WriteLine("无此文件");



         }
            charnum = length - konggenum;
            codeline = lines - nullline - noteline;

        }
        /// <summary>
        /// 文件中一行的情况
        /// </summary>
        /// <param name="str"></param>
         public void perLineWord(string str)
        {
//            int tempkongge = 0;
  //          int tempwords = 0;
            int i = 0;
       StreamReader sr = new StreamReader(sFilename, Encoding.Default);
while (str[i] == ' ' || str[i] == '\t')//去开头空格 { konggenum++; // tempkongge++; i++; if (i == str.Length) break; } while (i < str.Length) { //单词是以字母开头,字母、数字、_、组合的 if (('a' <= str[i] && str[i] <= 'z') || ('A' <= str[i] && str[i] <= 'Z')) { i++; while (('a' <= str[i] && str[i] <= 'z') || ('A' <= str[i] && str[i] <= 'Z') || ('0' <= str[i] && str[i] <= '9') || str[i] == '_') { i++; if (i == str.Length) break; } wordsnum++; // tempwords++; } else if (str[i] == ' ' || str[i] == '\t') { konggenum++; // tempkongge++; i++; } else i++; } // Console.WriteLine("字符数{0},,,{1}", i - tempkongge, tempwords); } } }

要读的文件

运行结果如下

扩展功能:

由于在基本功能中,没有考虑行的细分,必须要在扩展功能中考虑。在基本功能的基础上,信息又要再加上空行、代码行、注释行。

1、在void infile(sFilename)方法中进入void perLineWord(str)之前要判断读到的内容是否为空,若为空,空行加1,直接读下一行,若不为空,才进入 perLineWord(str)函数;

添加的代码如下:

                        if (str == "")
                        {
                            nullline++;



                        }
                        else
                        {
                            perLineWord(str);

                        }

 

2、在void perLineWord(str)中,一开始就要先将用一变量保存str中的前后空格去掉后的情况,若只有“{”、“}”或“”就将空行数加1,若是“}//”就讲注释行加1。之后的和基本功能的内容一样。

添加的代码如下:

            string temstr = str.TrimStart();//去除前后空格
             if(temstr =="{"||temstr =="}"||temstr =="")
             {
                 nullline++;
             }
             else if(temstr =="}//")
             {
                 noteline++;
             
             }

读取的文件如下

测试结果如下:

高级功能:

要想实现这个能够显示图形界面,就要添加新项——windows窗体。

新建好后,在vs窗口中生成一个窗体,在工具对话框里拖拽一个openFileDialog控件。然后点击窗体查看代码,增加一个filename字段和属性(用于保存选择的文件名),在Form1的构造函数里,增加当一个点击打开按钮后将获取的文件名给新增的filename字段。

代码如下:

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;

namespace count_wc
{
    public partial class Form1 : Form
    {
        string filename;//保存选择的文件名

        public  string Filename
        {
            get { return filename; }
            set { filename = value; }
        }

        public Form1()
        {
            InitializeComponent();
            if(openFileDialog1.ShowDialog()==DialogResult.OK)
            {
                filename  = openFileDialog1.FileName;//获取文件名

            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
     }
 

}

运行结果如下:

选择后点击打开

输入的实现:

在program类中main方法中将获取用户输入的信息保存在wininf中,当wininf==“-x”是就创建窗体,自然就能将文件对话框显示出来。再选择打开后总会有一个空白窗体显示出来,这个算一个不小的弊端了,由于时间紧急,现在还未处理好......(需注意的是main函数的上面必须要有“[STAThread]”,否则当命令是-x时程序就会出错)

之后就是要将输入信息拆分成命令信息和文件信息,再接着就是用一个方法public static void showResult(string sFilename,params object[] commond)来显示结果;

具体代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Windows.Forms;

namespace count_wc
{
    class Program
    {

        [STAThread]//没有它程序运行到-x条件时会出错
        static void Main(string[] args)
        {




            string wininf = ""; // 存储用户命令
            while (wininf != "exit")
            {
                string sFilename;
                Console.Write("WC.exe ");
                wininf = Console.ReadLine();  // 得到输入命令
                if (wininf == "-x")
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Form1 frm = new Form1();
                    Application.Run(frm);
                    sFilename = frm.Filename;
                    string[] commond = new string[3];

                    commond[0] = "-l";
                    commond[1] = "-c";
                    commond[2] = "-w";

                                     
                    showResult(sFilename, commond);
                    
                
                }
                else
                {
                    string[] arrwininf = wininf.Split(' '); // 分割命令
                    int infLength = arrwininf.Length;
                    string[] commod = new string[infLength - 1];
                    // 获取命令参数数组
                    for (int i = 0; i < infLength - 1; i++)
                    {
                        commod[i] = arrwininf[i];
                    }
                    // 获取文件名
                    sFilename = arrwininf[infLength - 1];
                    showResult(sFilename, commod);


                }


                Console.ReadKey();                
            }
        }

        public static void showResult(string sFilename,params object[] commond)
        {

            Count c1 = new Count();

            c1.infile(sFilename);
            int len = commond.Length;
            for (int i = 0; i < len; i++)
            {
                string com = (string)commond[i];
                switch (com)
                {


                    case "-c":
                        {
                            Console.WriteLine("字符数:{0}   ", c1.Charnum); break;
                        }
                    case "-w":
                        {
                            Console.WriteLine("单词数:{0}   ", c1.Wordsnum); break;
                        }
                    case "-l":
                        {
                            Console.WriteLine("行数:{0}   ", c1.Lines); break;
                        }
                    case "-a":
                        {
                            Console.WriteLine("代码行:{0}   空行:{1}   注释行:{2}", c1.Codeline, c1.Nullline, c1.Noteline); break;
                        }
                    case "-x":
                        {
                            Application.EnableVisualStyles();
                            Application.SetCompatibleTextRenderingDefault(false);
                            Application.Run(new Form1());
                            break;

                        }
                    default:
                        Console.WriteLine("字符数:{0}   单词数:{1}   行数:{2}", c1.Charnum, c1.Wordsnum, c1.Lines); break;

                }
            }
        }


    }
}

学习c#ing,,不喜勿怪.......              全代码见https://coding.net/u/zht01/p/WC_c/git

 

 

 

 

 

 

更进:::

在上面提到的输入-x,打开窗体选择文件后总会弹出一个空白窗体(不将窗体关掉,,后续的显示文件信息无法进行),,情况入下:

在进一步的学习c#中终于找到原因,,窗体被创建后,显示前会执行Load事件,,在该事件中可以对一些控件进行赋初值,,来在显示时将控件的初值显示出来,,如果不想让窗体显示,不需要在窗体上做任何操作,直接结束(这种情况很少),就在Load事件里直接将其关闭即this.Close();解决代码如下

        private void Form1_Load(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                filename = openFileDialog1.FileName;//获取文件名
                this.Close();

            }


        }

这样就不会有空白窗体出现,而直接进行后续的运行。。。。。

posted @ 2016-03-21 20:51  zht01  阅读(373)  评论(2编辑  收藏  举报