C语言程序执行correcttext函数后意外终止问题求助
程序执行correcttext后意外终止问题排查
问题场景
- 操作流程:输入1加载
coffee.txt文件,输入2调用correcttext函数加载englishWords.txt字典文件并进行文本比对 - 问题表现:
correcttext函数完成预期功能后,程序未返回主菜单,短暂停顿后意外终止
相关代码
#include <stdio.h> #include <stdlib.h> #include <string.h> int getchoice(); int print(char **x, int num); int entertext(char ***x); int correcttext(char ***x);// 仅输出文本中存在于字典里的单词 int countwords(char **x); int countletters(char **x); int main() { char **text = NULL; int choice=0; int num=0; while ((choice = getchoice()) != -1) { switch (choice) { case 1: num = entertext(&text); print(text, num); break; case 2: correcttext(&text); break; case 3: countwords(text); break; case 4: countletters(text); break; default: break; } } for (int i = 0; i < num; i++) { free(text[i]); } free(text); return 0; } int getchoice(void) { int choice; printf("\n1: 输入文本\n2: 校正文本\n3: 单词数量\n4: 字母数量\n-1: 退出\n>"); while (scanf("%d", &choice) != 1) { printf("无效选项... 请输入1-4之间的数字,或输入-1退出: "); while (getchar() != '\n'); } if (choice < -1 || choice > 4) { printf("无效选项... 请输入1-4之间的数字,或输入-1退出: "); exit(1); } return choice; } int print(char **x, int num) { for (int i = 0; i < num; i++) { printf(" %s\n", x[i]); } return 0; } int entertext(char ***x) { int size = 0; *x = NULL; char *word = NULL; FILE *file; file = fopen("coffee.txt", "r"); if (file == NULL) { printf("\n打开文件错误\n"); return 0; } while (fscanf(file, "%49s", word = malloc(50 * sizeof(char))) != EOF) { size++; *x = realloc(*x, size * sizeof(char *)); (*x)[size - 1] = malloc((strlen(word) + 1) * sizeof(char)); strcpy((*x)[size - 1], word); free(word); // 将word内容复制到(*x)后释放内存 } fclose(file); return size; } int correcttext(char ***x) { int dictSize = 0; char **dict = NULL; char *dictWord = NULL; // 重命名变量避免冲突 FILE *file; file = fopen("englishWords.txt", "r"); if (file == NULL) { printf("\n打开文件错误\n"); return 0; } while (fscanf(file, "%49s", dictWord = malloc(50 * sizeof(char))) != EOF) { dictSize++; dict = realloc(dict, dictSize * sizeof(char *)); dict[dictSize - 1] = malloc((strlen(dictWord) + 1) * sizeof(char)); strcpy(dict[dictSize - 1], dictWord); free(dictWord); // 将dictWord内容复制到dict后释放内存 } fclose(file); // 这里的问题:用字典的长度dictSize遍历text,而不是text的实际长度 // 同时,entertext加载的text每个元素是单个单词,不需要拆分 for (int i = 0; i < dictSize; i++) { for (int j = 0; (*x)[i][j] != '\0'; j++) { char word[30] = ""; int k = 0; while ((*x)[i][j] != ' ' && (*x)[i][j] != '\t' && (*x)[i][j] != '\n' && (*x)[i][j] != '\0') { word[k++] = (*x)[i][j++]; } word[k] = '\0'; for (int m = 0; m < dictSize; m++) { if (strcmp(word, dict[m]) == 0) { printf("%s\n", (*x)[i]); break; } } if ((*x)[i][j] == '\0') { break; } } } for (int i = 0; i < dictSize; i++) { free(dict[i]); } free(dict); return 0; } int countwords(char **x) { printf("单词数量, %s", x[0]); return 0; } int countletters(char **x) { printf("字母数量, %s", x[0]); return 0; }
问题原因及修复方案
核心问题1:correcttext遍历越界
correcttext用字典的单词数dictSize遍历text数组,但text的实际长度是main函数里的num,两者没有关联。如果字典单词数多于text的元素数,循环会访问text的越界内存,直接触发程序崩溃。
修复:修改correcttext参数,传入text的实际长度:
// 函数声明修改 int correcttext(char ***x, int textSize); // main函数调用修改 case 2: correcttext(&text, num); break; // correcttext实现修改 int correcttext(char ***x, int textSize) { // 字典加载部分不变 // 外层循环改为遍历text的实际长度 for (int i = 0; i < textSize; i++) { char *currentWord = (*x)[i]; for (int m = 0; m < dictSize; m++) { if (strcmp(currentWord, dict[m]) == 0) { printf("%s\n", currentWord); break; } } } // 字典释放部分不变 }
核心问题2:correcttext单词拆分逻辑冗余
entertext用fscanf("%49s")加载文件,会自动按空格分割单词,text的每个元素都是独立单词,不存在分隔符。原代码的拆分逻辑完全多余,还会引发额外内存访问错误。
修复:删除原函数中拆分单词的内层循环,直接用text[i]与字典比对。
次要问题:getchoice粗暴退出
输入无效选项时,原代码直接调用exit(1)终止程序,不符合返回主菜单重新输入的预期。
修复:替换exit(1)为循环重新获取输入:
int getchoice(void) { int choice; while (1) { printf("\n1: 输入文本\n2: 校正文本\n3: 单词数量\n4: 字母数量\n-1: 退出\n>"); while (scanf("%d", &choice) != 1) { printf("无效选项... 请输入1-4之间的数字,或输入-1退出: "); while (getchar() != '\n'); } if (choice >= -1 && choice <=4) { break; } printf("无效选项... 请输入1-4之间的数字,或输入-1退出: "); while (getchar() != '\n'); } return choice; }
内容的提问来源于stack exchange,提问作者BraVeHurt
相关产品推荐
相关产品推荐

