日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JAVA实现WC.exe功能

發布時間:2024/4/17 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JAVA实现WC.exe功能 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

項目要求

實現一個統計程序,它能正確統計程序文件中的字符數、單詞數、行數,以及還具備其他擴展功能,并能夠快速地處理多個文件。
具體功能要求:
程序處理用戶需求的模式為:

wc.exe [parameter] [file_name]

  • 基本功能列表:

    wc.exe -c file.c???? //返回文件 file.c 的字符數(實現)

    wc.exe -w file.c??? //返回文件 file.c 的詞的數目?(實現)

    wc.exe -l file.c????? //返回文件 file.c 的行數(實現)

  • 擴展功能:

  -s ? 遞歸處理目錄下符合條件的文件。(實現)
  -a ? 返回更復雜的數據(代碼行 / 空行 / 注釋行)。(實現)

  • 高級功能:

  -x 參數。這個參數單獨使用。如果命令行有這個參數,則程序會顯示圖形界面,用戶可以通過界面選取單個文件,程序就會顯示文件的字符數、行數等全部統計信息。

  (實現)

  需求舉例:
    wc.exe -s -a *.c?(實現)

    返回當前目錄及子目錄中所有*.c 文件的代碼行數、空行數、注釋行數。


?Github項目地址:https://github.com/kvhong/JAVA-to-bulid-wc.exe

?解題思路

主函數思路:通過輸入的命令來判斷執行各個功能函數,將輸入的命令分割為兩部分,第一部分是指令,第二部分是文件路徑,用指令來調用各個功能函數,文件路徑則作為參數輸入到各個功能函數中實現功能。

功能函數的共同部分:通過傳入的文件路徑并用Buffer流讀取文件內容,對文件內容進行相應統計然后輸出結果,需實現文件不存在或者路徑輸入錯誤提示。

詞數統計函數:需要去除空行、各種符號,將獨立的詞統計出來;

字符統計函數:需要去除空行、空格,將其余的內容的每一個單元都示為一個字符統計出來;

行數統計函數:文件中全部行數除結尾空行不算外其他都統計;

空行:TAB、空格、回車形成的空行都算入;

注釋行:單獨存在//、/*、*/的算入注釋行;

代碼行:除了空行、注釋行外屬于代碼行;

幫助:將各種命令列出,以更好的幫助使用;

?用戶使用說明

-c 文件(須包含文件完整路徑) 統計程序文件中的字符數
-w 文件(須包含文件完整路徑) 統計程序文件中的單詞數
-l 文件(須包含文件完整路徑) 統計程序文件中的行數
-a 文件(須包含文件完整路徑) 統計程序文件中的空行數、代碼行數、注釋行數
-s-a 文件路徑或者文件夾路徑 遞歸統計程序文件中的空行數、代碼行數、注釋行數(-s 命令不可單獨使用)
? 幫助
end 結束程序

?

?遇到的問題及解決方法

一開始不知道如何對詞、字符進行有效的分割,然后在網上學習到可以用正則表達式進行分割:使用下面語句將數字和和中英文標點符號和中文都替換成空格,以通過空格分割出各個詞。

str.replaceAll("[\\p{Nd}\\u9fa5-\\uffe5\\p{Punct}\\s&&[^-]]", " ");

使用下面的正則匹配器匹配注釋行和空行

Pattern nodeLinePattern = Pattern.compile("((//)|(/\\*+)|((^\\s)*\\*)|((^\\s)*\\*+/))+", Pattern.MULTILINE + Pattern.DOTALL); // 注釋匹配器(匹配單行、多行、文檔注釋) Pattern spaceLinePattern = Pattern.compile("^\\s*$"); // 空白行匹配器(匹配回車、tab鍵、空格)

?設計及代碼

?該程序通過一個主函數文件和一個方法函數文件組成。主函數文件用于輸入參數并判斷所輸入的各種操作以調用方法函數。方法函數用于實現各種功能:

文件詞數統計函數:getwordnumber()  命令:-w ?文件路徑(須包含完整路徑)

?

//文件詞統計函數int getwordnumber(String filename) throws IOException {int num=0;String[] strword = null;File file = new File(filename);if(file.exists()) {//讀取文件FileReader fr = new FileReader(filename);br = new BufferedReader(fr);String line = null;StringBuffer sbf = new StringBuffer();while((line=br.readLine())!= null) {sbf.append(line);String str = sbf.toString();//正則表達式替換符號str = str.replaceAll("[\\p{Nd}\\u9fa5-\\uffe5\\p{Punct}\\s&&[^-]]", " ");//按空格將內容分割strword = str.split("\\s+");num=strword.length;}br.close();fr.close();}else {System.out.println("文件不存在,請重新輸入文件!");}return num;}

?

文件字符數統計函數:getCharacternumber()  命令:-c ?文件路徑(須包含完整路徑)

?

//文件字符統計函數int getCharacternumber(String filename) throws IOException {int number = 0;String[] strword = null;File file = new File(filename);if(file.exists()) {//讀取文件FileReader fr = new FileReader(filename);br = new BufferedReader(fr);String line = null;String str=null;StringBuffer sbf = new StringBuffer();while((line=br.readLine())!= null) {sbf.append(line);str = sbf.toString();strword = str.split("\\s+");}for(int i=0;i<strword.length;i++) {Pattern pattern = Pattern.compile("[0-9a-zA-Z]*");Matcher matcher = pattern.matcher(strword[i]);if(matcher.find()) {number+=matcher.regionEnd();}}br.close();fr.close();}else {System.out.println("文件不存在,請重新輸入文件!");}return number;}

?

文件行數統計函數:getlinenumber()  命令:-l ?文件路徑(須包含完整路徑)

?

//文件行數統計函數int getlinenumber(String filename) throws IOException {int linenum = 0;File file = new File(filename);if(file.exists()) {//讀取文件FileReader fr = new FileReader(filename);//讀取文件行數LineNumberReader lnr = new LineNumberReader(fr);while(lnr.readLine()!= null) {linenum=lnr.getLineNumber();}lnr.close();fr.close();}else {System.out.println("文件不存在,請重新輸入文件!");}return linenum;}

?

統計文件或者文件夾中程序文件的空行、代碼行、注釋行,有遞歸文件目錄功能的函數,將遞歸功能一同實現在此函數中:diffline()  命令:-a 文件路徑或文件夾路徑/-s-a 文件路徑或文件夾路徑

?

//統計文件或者文件夾中程序文件的空行、代碼行、注釋行,有遞歸文件目錄功能int[] difflineGUI(File file) throws IOException {int spaceline = 0;int nodeline = 0;int codeline = 0;if (file == null || !file.exists()) {System.out.println(file + ",文件不存在!");}else {if (file.isDirectory()) {File[] files = file.listFiles(new FileFilter() {public boolean accept(File pathname) {return pathname.getName().endsWith(".java")|| pathname.isDirectory()||pathname.getName().endsWith(".c")||pathname.getName().endsWith(".cpp") ;}});//遞歸文件目錄for (File target : files) {diffline(target);}} else {BufferedReader bufr = null;// 將指定路徑的文件與字符流綁定bufr = new BufferedReader(new InputStreamReader(new FileInputStream(file)));// 定義匹配每一行的正則匹配器Pattern nodeLinePattern = Pattern.compile("((//)|(/\\*+)|((^\\s)*\\*)|((^\\s)*\\*+/))+", Pattern.MULTILINE + Pattern.DOTALL); // 注釋匹配器(匹配單行、多行、文檔注釋) Pattern spaceLinePattern = Pattern.compile("^\\s*$"); // 空白行匹配器(匹配回車、tab鍵、空格)// 遍歷文件中的每一行,并根據正則匹配的結果記錄每一行匹配的結果String line = null;while((line = bufr.readLine()) != null) {if (nodeLinePattern.matcher(line).find()) {nodeline ++;}else if (spaceLinePattern.matcher(line).find()) {spaceline ++;}else{codeline ++;} }}}int[] Sline= {spaceline,nodeline,codeline};return Sline;}

用于wctest.java文件:

//統計文件或者文件夾中程序文件的空行、代碼行、注釋行,有遞歸文件目錄功能void diffline(File file) throws IOException {int spaceline = 0;int nodeline = 0;int codeline = 0;if (file == null || !file.exists()) {System.out.println(file + ",文件不存在!");}else {if (file.isDirectory()) {File[] files = file.listFiles(new FileFilter() {public boolean accept(File pathname) {return pathname.getName().endsWith(".java")|| pathname.isDirectory()||pathname.getName().endsWith(".c")||pathname.getName().endsWith(".cpp") ;}});//遞歸文件目錄for (File target : files) {diffline(target);}} else {System.out.println("文件名:"+file.getAbsolutePath());// 將指定路徑的文件與字符流綁定BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileInputStream(file)));// 定義匹配每一行的正則匹配器Pattern nodeLinePattern = Pattern.compile("((//)|(/\\*+)|((^\\s)*\\*)|((^\\s)*\\*+/))+", Pattern.MULTILINE + Pattern.DOTALL); // 注釋匹配器(匹配單行、多行、文檔注釋) Pattern spaceLinePattern = Pattern.compile("^\\s*$"); // 空白行匹配器(匹配回車、tab鍵、空格)// 遍歷文件中的每一行,并根據正則匹配的結果記錄每一行匹配的結果String line = null;while((line = bufr.readLine()) != null) {if (nodeLinePattern.matcher(line).find()) {nodeline ++;}else if (spaceLinePattern.matcher(line).find()) {spaceline ++;}else{codeline ++;} }System.out.println("空行數:"+spaceline);System.out.println("注釋行數:"+nodeline);System.out.println("代碼行數:"+codeline);}}} 用于wctest.java的統計空行、注釋行、代碼行函數

幫助函數:help()  命令:?

?

//幫助函數void help(){System.out.println("-c 文件(須包含文件完整路徑) 統計程序文件中的字符數");System.out.println("-w 文件(須包含文件完整路徑) 統計程序文件中的單詞數");System.out.println("-l 文件(須包含文件完整路徑) 統計程序文件中的行數");System.out.println("-a 文件(須包含文件完整路徑) 統計程序文件中的空行數、代碼行數、注釋行數");System.out.println("-s-a 文件路徑或者文件夾路徑 遞歸統計程序文件中的空行數、代碼行數、注釋行數");System.out.println("-x 打開用戶界面");System.out.println("? 幫助");System.out.println("end 結束程序");}

主函數:wctest.java

?

package wc;import java.io.File; import java.io.IOException; import java.util.Scanner;public class wctest{private static Scanner scanner;public static void main(String[] args) throws IOException{String str = null;wcfunction wcf = new wcfunction();//循環詢問命令輸入while(true) {System.out.print("請輸入命令:");//命令輸入scanner = new Scanner(System.in);if(scanner.hasNext()) {str=scanner.nextLine();}//分割命令,第一個作為判斷第二個為文件路徑String[] strword = str.split(" ");if(strword.length==2) {if(strword[0].equals("-c")) {int chara=wcf.getCharacternumber(strword[1]);System.out.println("該文件的字符數:"+chara);}else if(strword[0].equals("-w")) {int word=wcf.getwordnumber(strword[1]);System.out.println("該文件的詞數:"+word);}else if(strword[0].equals("-l")) {int line=wcf.getlinenumber(strword[1]);System.out.println("該文件的行數:"+line);}else if(strword[0].equals("-a")) {File file = new File(strword[1]);int[] linenum=wcf.diffline(file);System.out.println("該文件的空行數:"+linenum[0]);System.out.println("該文件的注釋行數:"+linenum[1]);System.out.println("該文件的代碼行數:"+linenum[2]);}else if(strword[0].equals("-s-a")) {File file = new File(strword[1]);int[] linenum=wcf.diffline(file);System.out.println("該文件的空行數:"+linenum[0]);System.out.println("該文件的注釋行數:"+linenum[1]);System.out.println("該文件的代碼行數:"+linenum[2]);}}else {if(strword[0].equals("?")) {wcf.help();}else if(strword[0].equals("-x")) {wcGUI.main(null);}else if(strword[0].equals("end")) {break;}else {System.out.println("命令輸入錯誤,請重新輸入!");}}}} }

用戶界面文件:wcGUI.java  命令:-x

package wc;import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.BorderLayout; import javax.swing.JScrollPane; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.JLabel; import javax.swing.SwingConstants;public class wcGUI {private JFrame frmWc;private JTextField codenum;private JTextField wordnum;private JTextField linenum;private JTextField spaceline;private JTextField nodeline;private JTextField codeline;File file;wcfunction wcf=new wcfunction();/*** Launch the application.*/public static void main(String[] args) {EventQueue.invokeLater(new Runnable() {public void run() {try {wcGUI window = new wcGUI();window.frmWc.setVisible(true);} catch (Exception e) {e.printStackTrace();}}});}/*** Create the application.*/public wcGUI() {initialize();}/*** Initialize the contents of the frame.*/private void initialize() {frmWc = new JFrame();frmWc.setTitle("wc");frmWc.setResizable(false);frmWc.setBounds(280, 50, 800, 600);frmWc.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);JPanel panel = new JPanel();frmWc.getContentPane().add(panel, BorderLayout.CENTER);panel.setLayout(null);JScrollPane scrollPane = new JScrollPane();scrollPane.setBounds(291, 0, 493, 562);panel.add(scrollPane);JPanel panel_1 = new JPanel();scrollPane.setViewportView(panel_1);panel_1.setLayout(new BorderLayout(0, 0));JTextArea textArea = new JTextArea();textArea.setEditable(false);panel_1.add(textArea, BorderLayout.CENTER);JButton choosefile = new JButton("選擇文件");choosefile.setBounds(10, 32, 122, 23);panel.add(choosefile);JLabel filename = new JLabel("文件名:");filename.setBounds(10,70,80,23);panel.add(filename);JTextArea filepath = new JTextArea();filepath.setBounds(10, 95, 260, 40);filepath.setLineWrap(true);filepath.setWrapStyleWord(true); filepath.setEditable(false);panel.add(filepath);JButton code = new JButton("統計字符數");code.setBounds(10, 277, 100, 30);panel.add(code);JButton word = new JButton("統計詞數");word.setBounds(10, 317, 93, 30);panel.add(word);JButton line = new JButton("統計行數");line.setBounds(10, 357, 93, 30);panel.add(line);JButton diffline = new JButton("統計空行、注釋行、代碼行");diffline.setBounds(10, 397, 224, 30);panel.add(diffline);codenum = new JTextField();codenum.setBounds(120, 278, 93, 29);codenum.setEditable(false);panel.add(codenum);codenum.setColumns(10);wordnum = new JTextField();wordnum.setBounds(113, 318, 93, 30);wordnum.setEditable(false);panel.add(wordnum);wordnum.setColumns(10);linenum = new JTextField();linenum.setColumns(10);linenum.setBounds(113, 358, 93, 30);linenum.setEditable(false);panel.add(linenum);spaceline = new JTextField();spaceline.setColumns(10);spaceline.setBounds(70, 437, 93, 29);spaceline.setEditable(false);panel.add(spaceline);nodeline = new JTextField();nodeline.setColumns(10);nodeline.setBounds(70, 476, 93, 29);nodeline.setEditable(false);panel.add(nodeline);codeline = new JTextField();codeline.setColumns(10);codeline.setBounds(70, 515, 93, 30);codeline.setEditable(false);panel.add(codeline);JLabel label = new JLabel("空行");label.setHorizontalAlignment(SwingConstants.CENTER);label.setBounds(10, 437, 54, 29);panel.add(label);JLabel label_1 = new JLabel("注釋行");label_1.setHorizontalAlignment(SwingConstants.CENTER);label_1.setBounds(10, 476, 54, 29);panel.add(label_1);JLabel label_2 = new JLabel("代碼行");label_2.setHorizontalAlignment(SwingConstants.CENTER);label_2.setBounds(10, 515, 54, 30);panel.add(label_2);JLabel label_3 = new JLabel("個");label_3.setBounds(216, 277, 54, 30);panel.add(label_3);JLabel label_4 = new JLabel("個");label_4.setBounds(216, 317, 54, 30);panel.add(label_4);JLabel label_5 = new JLabel("行");label_5.setBounds(216, 357, 54, 30);panel.add(label_5);JLabel label_6 = new JLabel("行");label_6.setBounds(173, 437, 54, 30);panel.add(label_6);JLabel label_7 = new JLabel("行");label_7.setBounds(173, 476, 54, 30);panel.add(label_7);JLabel label_8 = new JLabel("行");label_8.setBounds(173, 515, 54, 30);panel.add(label_8);choosefile.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {JFileChooser filechooser = new JFileChooser(".");int result=filechooser.showOpenDialog(null);if(result == JFileChooser.APPROVE_OPTION){file=filechooser.getSelectedFile();if(file!=null) {if(textArea.getText()!=null) {textArea.setText("");}if(filepath.getText()!=null) {filepath.setText("");filepath.setText(file.getPath());}try {InputStreamReader read = new InputStreamReader(new FileInputStream(file), "GB2312");BufferedReader br = new BufferedReader(read);String line=null;while((line=br.readLine())!=null) {textArea.append(line+"\r\n");}br.close();} catch (IOException e1) {e1.printStackTrace();}}}}});code.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if(file.exists()) {String filename = file.getAbsolutePath();try {int chara=wcf.getCharacternumber(filename);codenum.setText(chara+"");} catch (IOException e1) {// TODO Auto-generated catch block e1.printStackTrace();}}}});word.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if(file.exists()) {String filename = file.getAbsolutePath();try {int word=wcf.getwordnumber(filename);wordnum.setText(word+"");} catch (IOException e1) {// TODO Auto-generated catch block e1.printStackTrace();}}}});line.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if(file.exists()) {String filename = file.getAbsolutePath();try {int line=wcf.getlinenumber(filename);linenum.setText(line+"");} catch (IOException e1) {// TODO Auto-generated catch block e1.printStackTrace();}}}});diffline.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if(file.exists()) {try {int[] line=wcf.difflineGUI(file);spaceline.setText(line[0]+"");nodeline.setText(line[1]+"");codeline.setText(line[2]+"");} catch (IOException e1) {// TODO Auto-generated catch block e1.printStackTrace();}}}});} } 用戶界面wcGUI.java

測試

已將程序打包成wc.exe文件,放在Github項目中。可直接打開exe文件輸入命令和文件路徑直接使用,也可使用CMD命令行運行wc.exe再輸入命令和文件路徑使用。

CMD命令行使用:

exe直接使用:

用戶界面:

?

代碼覆蓋率

代碼覆蓋率:97.5%

PSP

?

PSP2.1Personal Software Process Stages預估耗時(分鐘)實際耗時(分鐘)
Planning計劃4560
· Estimate· 估計這個任務需要多少時間4560
Development開發12901540
· Analysis· 需求分析 (包括學習新技術)80120
· Design Spec· 生成設計文檔4060
· Design Review· 設計復審 (和同事審核設計文檔)4040
· Coding Standard· 代碼規范 (為目前的開發制定合適的規范)3030
· Design· 具體設計120160
· Coding· 具體編碼780920
· Code Review· 代碼復審8090
· Test· 測試(自我測試,修改代碼,提交修改)120120
Reporting報告240380
· Test Report· 測試報告120220
· Size Measurement· 計算工作量3040
· Postmortem & Process Improvement Plan· 事后總結, 并提出過程改進計劃90120
?合計15751980

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

總結

先是從課堂上更加意識到制定設計流程的重要性,了解到計劃的設計不僅僅只存在于流程,對時間的規劃也是非常重要的。在編寫代碼過程中實質遇到的困難是在如何實現詞數的統計、正則表達式以及對文件目錄的遞歸實現。最后通過學習正則表達式實現了對詞數的統計,也進一步學習了正則表達式這一較為陌生的概念。也學會了一些新的插件和軟件的使用:Eclipse的EclEmma插件用于代碼覆蓋率的統計;Git Bash軟件對本地項目上傳到Github使用;exe4j軟件對JAVA項目進行EXE文件的打包使用。這次的項目作業對我來說是受益匪淺,對以后的項目實行有很大的幫助。

轉載于:https://www.cnblogs.com/K-mengmengpi/p/9614405.html

總結

以上是生活随笔為你收集整理的JAVA实现WC.exe功能的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。