You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从文本文件读取的字符串数组按长度排序时出现拼接问题求助

字符串数组按长度排序时出现字符串拼接异常

问题描述

逐行读取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 11:05:31