C语言通过CMD实现文件整词替换遇问题,求解决方案
解决C语言文件整词替换的问题
伙计,我看了你写的代码——能搞定单个字符替换,但整词替换就卡壳了对吧?咱们先拆解下原代码里的问题,再一步步改成能替换整词的版本。
原代码里的几个核心问题
- 类型不匹配+EOF判断坑:你在
SustChar里定义了char c[80];,但用c=fgetc(ptrf);赋值,fgetc返回的是单个字符(int类型,因为要兼容EOF的返回值),数组和单个字符类型完全不搭。而且while(!feof(ptrf))的写法会导致最后一次循环多读一次EOF,输出里可能出现乱码。 - 只处理单个字符:你现在的逻辑是比对
*argv[3]——也就是只取了命令行参数里旧词的第一个字符,这当然只能替换单个字符,没法识别完整的单词。
整词替换的实现思路
要替换整词,咱们得换个思路:逐行读取文件内容,在每一行里查找目标词的位置,把「目标词之前的内容」+「替换词」+「目标词之后的内容」依次写入新文件,循环处理完所有行就行。
修改后的完整代码
#include<stdio.h> #include<stdlib.h> #include<string.h> // 函数声明 void atributos(int argc, char *argv[]); void SustWord(char *argv[]); int main(int argc, char *argv[]) { // 先检查参数数量是否正确 if (argc != 6) { printf("用法错误!正确格式:.exeName origin.txt S oldword newword destiny.txt\n"); exit(1); } FILE *ptrf = fopen(argv[1], "r"); if (ptrf == NULL) { printf("无法打开源文件\n"); exit(1); } fclose(ptrf); atributos(argc, argv); return 0; } // 处理命令行参数的逻辑 void atributos(int argc, char *argv[]) { if (strcmp(argv[2], "S") == 0) { SustWord(argv); } else { printf("不支持的操作类型,目前仅支持S(替换)\n"); } } // 整词替换的核心函数 void SustWord(char *argv[]) { char line[1024]; // 用来存读取的每一行内容,长度可以根据需求调整 const char *old_word = argv[3]; const char *new_word = argv[4]; int old_len = strlen(old_word); int new_len = strlen(new_word); FILE *src_file = fopen(argv[1], "r"); FILE *dest_file = fopen(argv[5], "w"); if (src_file == NULL || dest_file == NULL) { printf("文件打开失败\n"); exit(1); } // 逐行读取文件 while (fgets(line, sizeof(line), src_file) != NULL) { char *pos = line; // 在当前行里循环查找旧词的位置 while ((pos = strstr(pos, old_word)) != NULL) { // 先把旧词之前的内容写入目标文件 fwrite(line, 1, pos - line, dest_file); // 写入替换词 fwrite(new_word, 1, new_len, dest_file); // 把指针移到旧词之后,继续查找 pos += old_len; } // 写入当前行剩下的内容(最后一次查找后到行尾的部分) fwrite(pos, 1, strlen(pos), dest_file); } fclose(src_file); fclose(dest_file); printf("替换完成!\n"); }
代码说明
- 参数校验:在
main里先检查命令行参数数量是否为6个,避免用户输入错误。 - 逐行读取:用
fgets读取每一行,避免单个字符处理的局限性。 - 整词查找:用
strstr函数在当前行里查找旧词的位置,找到后拆分内容写入。 - 文件操作安全:增加了文件打开失败的判断,避免程序崩溃。
你在CMD里还是用原来的语法:exeName origin.txt S oldword newword destiny.txt就行,现在就能正常替换整词啦。
内容的提问来源于stack exchange,提问作者CarmesiD




