求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
C++文件的批处理
 

发布于2012-8-7

 

一、统计代码行数

几个星期前做了个统计代码的小程序,对文件的批处理需要获取文件列表,因为是在windows下操作的,所以百度到一个系统调用system("dir /a /b >> file_list.txt");

功能就是把当前目录下的所有文件名写到file_list.txt文件中去。这样我就得到了所有的文件名,从而就可以对文件批处理了。对每一个文件的操作就是首先读取文件名,然后就打开文件,接着一行一行的读文件,没读取一行文件就累计代码行数。过程很简单,代码如下:

 1 #include <iostream>
 2 #include <fstream>
 3 #include <cstdlib>
 4 
 5 using std::cout;
 6 using std::endl;
 7 using std::fstream;
 8 using std::string;
 9 
10 int main(int argc, char **argv)
11 {
12     //创建文件名列表文件,若存在则清空文件
13     fstream file_list("file_list.txt",std::ios::out);
14     file_list.close();
15 
16     //写入文件名列表到file_list.txt
17     system("dir /a /b >> file_list.txt");
18     
19     long sum_code = 0;
20     fstream code_file;
21     file_list.open("file_list.txt", std::ios::in);
22     string str_line = "";
23     string t_str = "";
24     unsigned int loc = 0;//查找文件名中的"."
25     string str_last = "";
26     
27     while (!file_list.eof())
28     {
29         getline(file_list,str_line);
30         loc = str_line.find(".",0);
31 //        cout << "loc = " << loc << endl;
32         if (loc != string::npos)
33         {
34             str_last = str_line.substr(loc);
35 //            cout << "str_last = " << str_last << endl;
36         }
37         else
38         {
39             continue;
40         }
41         
42         if (str_last.compare(".h") == 0
43         || str_last.compare(".c") == 0
44         || str_last.compare(".cpp") == 0)
45         {
46             code_file.open(str_line.c_str(),std::ios::in);
47             cout << "文件名 : " << str_line << endl;
48         }
49         else
50         {
51             continue;
52         }
53         
54         //读文件行数
55         while (!code_file.eof())
56         {
57             getline(code_file,t_str);
58             cout << t_str << endl;
59             sum_code++;
60         }
61         code_file.close();
62         cout << endl;
63     }
64     file_list.close();
65     
66     cout << "代码行数:" << sum_code << endl;
67     system("pause");
68 
69     return 0;
70 } 

二、批量删除文件中的某一行

今天做的修改时有原因的,因为我正在将http://www.cplusplus.com/reference/做成一个chm文件(供离线查寻的文档)。通过Teleport Ultra软件获取到网站的代码后,代码有好多是404页面和用户登录页面。这些文件我是通过手工删除的,删除404页面就是根据文件大小来删除的(不会傻到对着一千多个文件一个一个打开查看,毕竟404页面大小是一样的)。删除登录页面是根据文件名的。文件名有new.cgi?或者edit.cgi?等等,是按文件名排序删除的。

然后使用EasyCHM软件开始制作。制作后出现了问题,打开页面预览出现

我郁闷了,我就打开源代码,找到了有这么一行,打开每一文件都这样。

因此,我就想到之前写的代码统计的程序了,然后我就做了个微小的修改把这一行删除掉。在上面的55行的while中加入

if (t_str == "onPrint.print();")
{
  cout << t_str << endl;
  continue;
}  

因为要修改源文件,我就通过一个临时文件来存储修改后的文件,文件修改完成后再将临时文件的内容复制到源文件中,复制文件的代码段:

        //复制回来
        out_tmp.open("tmp",std::ios::in);
        code_file.open(str_line.c_str(),std::ios::out);
        char ch;
        while(code_file && out_tmp.get(ch))
        {
            code_file.put(ch);
        }
        code_file.close();
        out_tmp.close();
        cout << "修改" << str_line << "完成" << endl;

三、批量删除文件中的某一代码段

这样对所有文件批处理后又有了新问题,弹出的脚本对话框和上面的类似。这样慢慢删岂不会累死,我能不能把所有的<script></<script>都删除掉呢?我就先手动删除一个文件的所有<script> ... </<script>。然后放到EasyCHM软件中,结果真的好了,不弹出脚本错误对话框了(脚本都没了,何来脚本错误呢?)。这样我就放心了,因为脚本文件删除了不影响htm文件的界面。这样我就开始修改代码了,同样修改读文件那一段代码。

            if (t_str.substr(0,7) == "<script")
            {
                while (!code_file.eof() 
                        && t_str != "</script>" 
                        && t_str.substr(t_str.size()>9?t_str.size()-9:0) != "</script>")
                {
                    cout << t_str << endl;
                    getline(code_file,t_str);
                }
                cout << t_str << endl;
                getline(code_file,t_str);
            } 

这是放在读文件循环中的代码。每次读到一行的头几个字符是"<script"就对接下来的字符处理知道读到"</script>"。因为我查了所有代码都类似,"<script"在每行的行首,"</script>"在字符串的末尾后者行首,所以就只是简单的判断了下,没有考虑到一行中既有脚本文件又有非脚本文件的情况:

<script type="text/javascript">google_ad_height = 60;</script>
<div id="I_midclear"></div>
</div><script type="text/javascript"src="show_ads.js" 
tppabs="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>

我想也不会有人会把这种代码写成一行吧。接着就测试了一个htm文件,结果可以了,只是有一个bug,运行一次后还残留着<script> ... </<script>。再运行一次就清理完了。先看有bug的代码:

有bug但是可以完成任务的代码

接下来就是查找bug了,然后在解决bug,记住哦,做这些操作记得备份之前原版的htm文件哦,要不然你弄完后原版的文件没了怎么来找bug,怎么测试啊。关键还是看这里(循环读文件人后再判断的代码段):

 1         fstream out_tmp("tmp",std::ios::out);
 2         //读文件行数
 3         while (!code_file.eof())
 4         {
 5             getline(code_file,t_str);
 6             if (t_str.substr(0,7) == "<script")
 7             {
 8                 while (!code_file.eof() 
 9                         && t_str != "</script>" 
10                         && t_str.substr(t_str.size()>9?t_str.size()-9:0) != "</script>")
11                 {
12                     cout << t_str << endl;
13                     getline(code_file,t_str);
14                 }
15                 cout << t_str << endl;
16                 getline(code_file,t_str);
17             }
18             out_tmp << t_str << endl;
19             sum_code++;
20         }
21         code_file.close();
22         out_tmp.close();
23         cout << endl; 

发现了问题,是因为执行了一次删除脚本后,接下来的脚本紧接在其下一行,读取的时候跳过了这一次检查,这样简单啊,只执行一次判定<script>,我把if改成while就可以了


相关文章

深度解析:清理烂代码
如何编写出拥抱变化的代码
重构-使代码更简洁优美
团队项目开发"编码规范"系列文章
相关文档

重构-改善既有代码的设计
软件重构v2
代码整洁之道
高质量编程规范
相关课程

基于HTML5客户端、Web端的应用开发
HTML 5+CSS 开发
嵌入式C高质量编程
C++高级编程
   

Visual C++编程命名规则
任何时候都适用的20个C++技巧
C语言进阶
串口驱动分析
轻轻松松从C一路走到C++
C++编程思想
更多...   


C++并发处理+单元测试
C++程序开发
C++高级编程
C/C++开发
C++设计模式
C/C++单元测试


北京 嵌入式C高质量编程
中国航空 嵌入式C高质量编程
华为 C++高级编程
北京 C++高级编程
丹佛斯 C++高级编程
北大方正 C语言单元测试
罗克韦尔 C++单元测试
更多...