从文本文件读取的字符串数组按长度排序时出现拼接问题求助
字符串数组按长度排序时出现字符串拼接异常
问题描述
逐行读取txt文件内容存入字符串数组,按字符串长度排序后,输出出现两个字符串被拼接的异常情况。
原文件内容
X&Y X|Y !X (X|Y)|Z (X&Y)|Z (X&Y)&Z (X&Y)|Z&(A|B ((X|Y)|Z)&((A|B)|(C&D)) (X&Y)|(Z&(A|B)) (A|B)&(!C) A|(B&(C&(D|E))) ((X|Y)|(Z&(A|B)))|((C&D)&(D|E)) (A|B)|(C&D)&(D|E) !A&(B|C) (A|B)|(C|D)&(D
异常排序输出
!X X|Y X&Y (X|Y)|Z (X&Y)|Z (X&Y)&Z !A&(B|C) (A|B)&(!C) (X&Y)|Z&(A|B (A|B)|(C|D)&(DA|(B&(C&(D|E))) // 此处异常:两个字符串被拼接 (X&Y)|(Z&(A|B)) (A|B)|(C&D)&(D|E) ((X|Y)|Z)&((A|B)|(C&D)) ((X|Y)|(Z&(A|B)))|((C&D)&(D|E))
现有代码
//Sort function void sort(char str[][MAXLEN], int number_of_elements) { int d, j; char temp[100]; for (d = 0; d < number_of_elements - 1; d++) { for (j = 0; j < number_of_elements - d - 1; j++) { if (strlen(str[j]) < strlen(str[j + 1])) { strcpy(temp, str[j]); strcpy(str[j], str[j + 1]); strcpy(str[j + 1], temp); } } } } int main() { FILE *dat; int number_of_elements; char str[MAX][MAXLEN]; int i = 0; dat = fopen("ulaz.txt", "r"); if (dat == NULL) { printf("Error"); } while (!feof(dat) && !ferror(dat)) { if (fgets(str[i], 100, dat) != NULL) i++; } number_of_elements = i; fclose(dat); sort(str, number_of_elements); for (int d = 0; d < i; d++) { printf("%s", str[d]); } return 0; }
问题原因及解决方法
1. 缓冲区溢出(核心问题)
排序函数中temp数组固定为100字节,而字符串数组str的每个元素大小是MAXLEN。当字符串长度超过99时,strcpy(temp, str[j])会超出temp的容量,触发缓冲区溢出,破坏相邻内存中的字符串数据,导致输出时出现拼接。
修复方式:将temp的大小改为MAXLEN,确保能容纳最长的字符串:
char temp[MAXLEN];
2. fgets读取长度不匹配
fgets(str[i], 100, dat)中的100与str元素的MAXLEN不一致,若MAXLEN>100会导致字符串被截断,同时无法保证终止符\0的正确写入。
修复方式:将读取长度改为MAXLEN:
if (fgets(str[i], MAXLEN, dat) != NULL)
3. 循环读取逻辑不规范
原循环用!feof(dat)作为条件可能导致冗余的循环判断,同时缺少数组边界检查,可能导致数组越界。
修复方式:改为直接判断fgets返回值,并添加数组边界限制:
while (i < MAX && fgets(str[i], MAXLEN, dat) != NULL) { i++; }
额外说明
现有排序函数实现的是降序排序(长字符串在前),如果需要升序,只需将判断条件改为:
if (strlen(str[j]) > strlen(str[j + 1]))
内容的提问来源于stack exchange,提问作者Andew Tayloe
相关产品推荐
相关产品推荐

