• C++文件的批处理


      好久没写文章了,今天又来做个学习C++的小总结。

    一、统计代码行数

      个星期前做了个统计代码的小程序,对文件的批处理需要获取文件列表,因为是在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;

    全部代码如下:

    删除指定行的代码
     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(".htm") == 0)
    43         {
    44             code_file.open(str_line.c_str(),std::ios::in);
    45             cout << "文件名 : " << str_line << endl;
    46         }
    47         else
    48         {
    49             continue;
    50         }
    51         
    52         fstream out_tmp("tmp",std::ios::out);
    53         //读文件行数
    54         while (!code_file.eof())
    55         {
    56             getline(code_file,t_str);
    57             if (t_str == "onPrint.print();")
    58             {
    59                 cout << t_str << endl;
    60                 continue;
    61             }
    62             out_tmp << t_str << endl;
    63             sum_code++;
    64         }
    65         code_file.close();
    66         out_tmp.close();
    67         cout << endl;
    68         
    69         //复制回来
    70         out_tmp.open("tmp",std::ios::in);
    71         code_file.open(str_line.c_str(),std::ios::out);
    72         char ch;
    73         while(code_file && out_tmp.get(ch))
    74         {
    75             code_file.put(ch);
    76         }
    77         code_file.close();
    78         out_tmp.close();
    79         cout << "修改" << str_line << "完成" << endl;
    80     }
    81     file_list.close();
    82     
    83     cout << "代码行数:" << sum_code << endl;
    84     system("pause");
    85 
    86     return 0;
    87 }

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

      样对所有文件批处理后又有了新问题,弹出的脚本对话框和上面的类似。这样慢慢删岂不会累死,我能不能把所有的<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但是可以完成任务的代码
     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(".htm") == 0)
    43         {
    44             code_file.open(str_line.c_str(),std::ios::in);
    45             cout << "文件名 : " << str_line << endl;
    46         }
    47         else
    48         {
    49             continue;
    50         }
    51         
    52         fstream out_tmp("tmp",std::ios::out);
    53         //读文件行数
    54         while (!code_file.eof())
    55         {
    56             getline(code_file,t_str);
    57             if (t_str.substr(0,7) == "<script")
    58             {
    59                 while (!code_file.eof() 
    60                         && t_str != "</script>" 
    61                         && t_str.substr(t_str.size()>9?t_str.size()-9:0) != "</script>")
    62                 {
    63                     cout << t_str << endl;
    64                     getline(code_file,t_str);
    65                 }
    66                 cout << t_str << endl;
    67                 getline(code_file,t_str);
    68             }
    69             out_tmp << t_str << endl;
    70             sum_code++;
    71         }
    72         code_file.close();
    73         out_tmp.close();
    74         cout << endl;
    75         
    76         //复制回来
    77         out_tmp.open("tmp",std::ios::in);
    78         code_file.open(str_line.c_str(),std::ios::out);
    79         char ch;
    80         while(code_file && out_tmp.get(ch))
    81         {
    82             code_file.put(ch);
    83         }
    84         code_file.close();
    85         out_tmp.close();
    86         cout << "修改" << str_line << "完成" << endl;
    87     }
    88     file_list.close();
    89     
    90     cout << "代码行数:" << sum_code << endl;
    91     system("pause");
    92 
    93     return 0;
    94 }

      下来就是查找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就可以了,修改后的代码如下:

    最后代码
     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(".htm") == 0)
    43         {
    44             code_file.open(str_line.c_str(),std::ios::in);
    45             cout << "文件名 : " << str_line << endl;
    46         }
    47         else
    48         {
    49             continue;
    50         }
    51         
    52         fstream out_tmp("tmp",std::ios::out);
    53         //读文件行数
    54         while (!code_file.eof())
    55         {
    56             getline(code_file,t_str);
    57             while (t_str.substr(0,7) == "<script")
    58             {
    59                 while (!code_file.eof() 
    60                         && t_str != "</script>" 
    61                         && t_str.substr(t_str.size()>9?t_str.size()-9:0) != "</script>")
    62                 {
    63                     cout << t_str << endl;
    64                     getline(code_file,t_str);
    65                 }
    66                 cout << t_str << endl;
    67                 getline(code_file,t_str);
    68                     
    69             }
    70             out_tmp << t_str << endl;
    71             sum_code++;
    72         }
    73         code_file.close();
    74         out_tmp.close();
    75         cout << endl;
    76         
    77         //复制回来
    78         out_tmp.open("tmp",std::ios::in);
    79         code_file.open(str_line.c_str(),std::ios::out);
    80         char ch;
    81         while(code_file && out_tmp.get(ch))
    82         {
    83             code_file.put(ch);
    84         }
    85         code_file.close();
    86         out_tmp.close();
    87         cout << "修改" << str_line << "完成" << endl;
    88     }
    89     file_list.close();
    90     
    91     cout << "代码行数:" << sum_code << endl;
    92     system("pause");
    93 
    94     return 0;
    95 }

      后,我也完成了http://www.cplusplus.com/reference/离线chm版本。大家玩这个注意备份文件哦!!!

    附件:

      [1]  统计代码行数

      [2]  删除htm文件中脚本代码段

      [3] c++标准参考文档离线chm版

  • 相关阅读:
    pyspider 在ubuntu上安装失败怎么搞?
    怎么在项目中使用前端包管理器bower和构建工具gulp
    Asp.net mvc 实时生成缩率图到硬盘
    如果转载优酷、土豆视频等,怎么让视频自适应宽度?
    C语言II博客作业04
    C语言I博客作业03
    C语言II博客作业02
    C语言II博客作业01
    学期总结
    The first essay
  • 原文地址:https://www.cnblogs.com/hanxi/p/2603584.html
Copyright © 2020-2023  润新知