C语言文件乱码注释删除—可传入待修改的文件名

目录

为什么要写这篇

可以传入文件名,那文件名如何传递进去呢?

关于可以不传入要保存的文件名,那是如何实现的呢?

可以传入文件名的好处是什么?

这是个实用的可执行文件吗?

后期可改进的


为什么要写这篇

前几天因为移植,遇到注释乱码问题,因为最终确定改不回来了,干脆把乱码注释都删掉,就用C语言实现了。

我也是参考了网上的一篇文章,但是和他/她的不同点是,我按照自己的思路对程序重新实现了,思路不够清晰的话,即使是很简短的代码看起来也是相当费劲的一件事。同时根据自己的习惯写上了注释,我对写注释这件事还是相当执着的,即使在此花费一定量的时间。

同时为了实用性,可以传入要删除注释的文件名,根据我之前做的那个将快递单号传输到Excel 的方式,给要保存的文件重新命名,与那个不同的是,这个除了可以传入要删除注释的文件名外,还可以传入要保存的文件名。

可以传入文件名,那文件名如何传递进去呢?

熟悉main函数传参数的小伙伴应该知道通过命令行,可执行文件后面写入要传入的参数,然后回车就好了。这应该在嵌入式Linux的程序上比较常见。传入的字符串是文件名的话就可以将 待修改的文件名传进去,同理也可以将要保存的文件名传进去。

关于可以不传入要保存的文件名,那是如何实现的呢?

首先要知道要要保存的文件名与要修改的源文件的关系,通过要修改的源文件的文件名确定要保存的文件名。

可以传入文件名的好处是什么?

如果文件名是源文件内的一个字符串变量,那么就需要每次都修改然后重新编译,就需要使用者配置相应的编译环境。而如今这种已经生成可执行文件,即使没有配置相应的编译环境,也可以执行,只需要cmd命令窗口进入相应文件目录,然后传入文件名参数就可以了。这一步即使是配置相应编译环境也需要这么执行。

这是个实用的可执行文件吗?

通过cmd命令窗口进入相应的目录,然后手动输入,回车。。。那太不友好了,还好我知道这问题如何解决,bat脚本,通过鼠标右键的编辑打开bat脚本文件,输入要修改的文件名,保存后双击就会生成删除注释后的源文件了。至于为什么是main.exe 那就是Makefile决定的了。Makefile的打开方式就不能通过鼠标右键的编辑了。我常用的是VS code 和 Notepad++

Makefile中内容如下,想了解为什么这么写网上应该有大把的资料吧,比如C语言中文网

如果报出某种警告的话,把bat脚本文件中make那一行删掉,这是编译生成可执行文件用的,没有配置编译环境这一步是不需要的。

后期可改进的

更理想的功能是想要删除注释的源文件放在同一目录下,然后双击运行bat脚本,就生成了删除注释后的源文件。

或者将DeleteNotes.exe 和 DeleteNotes.bat 放在一个目录下,该目录下的所有源文件都删除注释,新生成一个文件夹,用于存放删除注释后的源文件。

我把实现逻辑写在注释里了,可以结合着代码理解一下。文件我上传到CSDN上了:DeleteNotes.zip,有需要的可以拿来试试。

/**
 * @file DeleteNotes.c
 * @brief   删除C语言文件中的所有注释
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date           <th>Version     <th>Author      <th>Description
 * <tr><td>2021-02-01     <td>1.0.0     <td>Lv_*_Guang     <td>修改内容描述
 * </table>
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>

#define MAX_LENGTH      300


/**
 * main
 * @brief   查找// 和 / *  * / , 然后删除注释
 * @param   argc 参数描述: 参数个数,以空格分隔得到,不需要输入
 * @param   argv 参数描述: 字符串数组
 * @retval  int 返回值描述: 无
 * @note    如果参数个数小于2,说明没有没有文件要处理,提示并返回
 * @note    如果参数个数为2,第二个字符串为要操作的文件名
 * @note    如果参数个数大于2,说明第三个字符串为要保存的文件名
 * @note    尝试打开和 写入文件(写入时若文件不存在则自动创建)
 * @note    以MAX_LENGTH 为缓存大小,个人试着一行代码基本不会超过这些字符,超过也无所谓
 * @note    fgets 获取MAX_LENGTH - 1 个字符,最后一个字符要留给'\0' ,如果遇到换行符'\n',即使缓存未满也不再读取,
 * @note    可能是因为'\n' 后面紧接着是'\0',C标准库中字符串操作的函数都将'\0' 作为结束符
 * @note    查询到特定字符后将原本读取的某些字符串判定为注释,然后清0
 * @note    将剩余字符写入到要保存的文件中
 */
int main(int argc, char* argv[])
{
    FILE *fp, *fp1;
    char str[MAX_LENGTH] = "";
    bool multi_lines_notes = false;
    char str_open_file[30] = "";
    char str_save_file[30] = "";

    if(argc <= 1)
    {
        printf("There are no files to modify! \n");
        exit(0);
    }else if(argc <= 2)
    {
        char str_filename[30] = "";
        char str_fileextension[30] = "";

        sprintf(str_open_file, "%s", argv[1]);
        char* suffix = strrchr(str_open_file, '.');
        memcpy(str_filename, str_open_file, strlen(str_open_file) - strlen(suffix));
        memcpy(str_fileextension, suffix, strlen(suffix));
        sprintf(str_save_file, "%s%s%s", str_filename, "_modify", str_fileextension);

        printf("str_open_file is : %s \n", str_open_file);
        printf("str_save_file is : %s \n", str_save_file);
    }else
    {
        sprintf(str_open_file, "%s", argv[1]);
        sprintf(str_save_file, "%s", argv[2]);

        printf("str_open_file is : %s \n", str_open_file);
        printf("str_save_file is : %s \n", str_save_file);
    }

    if ((fp = fopen(str_open_file, "r")) == NULL)
    {
        printf("open file error!\n");
        exit(0);
    }
    if ((fp1 = fopen(str_save_file, "w")) == NULL)
    {
        printf("new_built file error!\n");
        exit(0);
    }

    while (fgets(str, MAX_LENGTH - 1, fp) != NULL)  //缓冲区满返回,遇到换行符返回
    {
        for (uint16_t i = 0; i < MAX_LENGTH - 1; i++)
        {
            if (str[i] == '/' && str[i - 1] == '/')     ///< //
            {
                memset(str + i - 1, '\0', MAX_LENGTH - i);
                str[i - 1] = '\n';
                str[i] = '\0';
            }

            if (str[i] == '*' && str[i - 1] == '/')     ///< /*
            {
                memset(str, '\0', i);
                multi_lines_notes = true;
                fputs(str, fp1);
            }

            if (str[i] == '/' && str[i - 1] == '*')     ///< */
            {
                memset(str, '\0', i);

                multi_lines_notes = false;
            }
        }

        if (! multi_lines_notes)
        {
            fputs(str, fp1);
        }
    }

    fclose(fp);
    fclose(fp1);
    return 0;
}

版权声明:本文为quanquanxiaobu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>