C语言字符串压缩代码调试:重复字符转[字符$次数]格式
字符串连续重复字符替换问题调试
问题描述
需要实现字符串处理任务:将字符串中连续重复的字符替换为「字符+$+重复次数」格式。
- 输入示例:
"aaa bbuvvvvo" - 期望输出:
"a$3 b$2uv$4o" - 当前错误输出:
"a$3 b$2v$4vo"
原代码
#include <stdio.h> #include <string.h> #define CAPACITY 255 #define MAX_NUMBER 10 void Output(char readFile[], char outputFile[], char string[]); void changeString(char string[], char newString[]); int main() { char readFile[CAPACITY]; char outputFile[CAPACITY]; char string[CAPACITY]; // Input file's name printf("Iveskite teksto failo varda: "); scanf("%s", &readFile); // Output file's name printf("Iveskite teksto faila i kuri bus isvedamas atsakymas: "); scanf("%s", &outputFile); Output(readFile, outputFile, string); return 0; } // Scanning file void Output(char readFile[], char outputFile[], char string[]) { char newString[CAPACITY]; FILE *input, *output; input = fopen(readFile, "r"); while(fscanf(input, "%s", string) != EOF) { changeString(string, newString); printf("%s\n", newString); } } // Changing string to wanted string void changeString(char string[], char newString[]) { char number[MAX_NUMBER]; int symbols = 0; int j; for(int i = 0; string[i] != '\0'; ++i) { int temp = i; newString[i] = string[i]; if(newString[i] == string[i + 1]) { j = i; while(string[j] == string[i]) { ++symbols; ++j; } // Changing int to char sprintf(number, "%d", symbols); newString[i + 1] = '$'; i += 2; newString[i] = number[0]; symbols = 0; } } }
错误原因分析
- 索引管理混乱:同时用原字符串的
i索引操作新字符串,导致新字符串写入位置错位,处理完重复字符后残留原字符串的多余字符(比如示例中的最后一个v)。 - 重复次数计算错误:用
symbols计数器初始值为0,循环自增后得到的次数比实际少1,且逻辑冗余。 - 未处理多位数次数:仅取数字字符串的第一位,若重复次数超过9会丢失后续数位。
- 新字符串未终止:未添加
'\0'终止符,输出可能出现乱码或残留旧数据。 - 文件读取逻辑缺陷:
fscanf("%s")会跳过空格,无法处理带空格的输入;未处理文件打开失败的情况;未将结果写入输出文件。 scanf参数错误:数组名本身是地址,无需加&,原代码中scanf("%s", &readFile)属于错误用法。
修复后的代码
#include <stdio.h> #include <string.h> #define CAPACITY 255 #define MAX_NUMBER 10 void Output(char readFile[], char outputFile[], char string[]); void changeString(char string[], char newString[]); int main() { char readFile[CAPACITY]; char outputFile[CAPACITY]; char string[CAPACITY]; // 输入文件名 printf("Iveskite teksto failo varda: "); scanf("%s", readFile); // 输出文件名 printf("Iveskite teksto faila i kuri bus isvedamas atsakymas: "); scanf("%s", outputFile); Output(readFile, outputFile, string); return 0; } // 读取文件并处理输出 void Output(char readFile[], char outputFile[], char string[]) { char newString[CAPACITY]; FILE *input = fopen(readFile, "r"); if (!input) { perror("Failed to open input file"); return; } FILE *output = fopen(outputFile, "w"); if (!output) { perror("Failed to open output file"); fclose(input); return; } // 读取整行保留空格,处理换行符 while (fgets(string, CAPACITY, input) != NULL) { size_t len = strlen(string); if (len > 0 && string[len-1] == '\n') { string[len-1] = '\0'; } changeString(string, newString); printf("%s\n", newString); fprintf(output, "%s\n", newString); } fclose(input); fclose(output); } // 转换字符串格式 void changeString(char string[], char newString[]) { int i = 0; // 原字符串遍历索引 int k = 0; // 新字符串写入索引 int len = strlen(string); while (i < len) { char current = string[i]; int count = 1; // 统计连续重复次数 while (i + count < len && string[i + count] == current) { count++; } // 写入当前字符 newString[k++] = current; // 重复次数大于1时,写入$和次数 if (count > 1) { newString[k++] = '$'; char num_str[MAX_NUMBER]; sprintf(num_str, "%d", count); strcpy(&newString[k], num_str); k += strlen(num_str); } // 跳到下一个不同字符的位置 i += count; } // 添加字符串终止符 newString[k] = '\0'; }
修复点说明
- 分离索引管理:用
i遍历原字符串,k独立管理新字符串的写入位置,避免索引冲突。 - 简化次数计算:通过
i + count直接遍历统计重复次数,逻辑更简洁准确。 - 支持多位数次数:用
strcpy完整写入数字字符串,处理次数大于9的场景。 - 添加终止符:确保新字符串符合C语言字符串规范。
- 修复文件操作:用
fgets读取整行保留空格;增加错误处理;实现结果写入输出文件。 - 修正
scanf参数:去掉数组名前的多余&。
内容的提问来源于stack exchange,提问作者Kurbamit
相关产品推荐
相关产品推荐

