如何对已读取到二维char数组的文本行按长度排序?
问题描述
我正在编写一个C程序,该程序打开input.txt文件并将其中的行读取到二维char数组中,以便按行长度对这些行进行排序。
测试用的input.txt内容:
1. hello world 2. john Jones at Brook Mountains 3. Frozen Styx 4. altair 5. John Doe and Jane Doe 6. Cranium
我当前的source.c代码如下:
#define MAX_LINES 100 #define MAX_LEN 1000 int main(void) { char data[MAX_LINES][MAX_LEN]; FILE* fread = fopen("C:\\Users\\EXAMPLE\\desktop\\input.txt", "r"); if (fread == NULL) { printf("ERROR\n"); return 1; } int line = 0; while (!feof(fread) && !ferror(fread)) { if (fgets(data[line], MAX_LEN, fread) != NULL) { line++; } } fclose(fread); for (int i = 0; i < line; i++) { printf("%s", data[i]); } return 0; }
目前已成功将文件内容读取到二维数组并能打印测试,但不知道如何按行长度排序。试过两种方案都不满足需求:第一种无效,第二种只能按字母排序。
解决方案
要实现按行长度排序,可利用C标准库的qsort函数,自定义比较函数对比两行长度,具体修改如下:
完整修改后的代码
#include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX_LINES 100 #define MAX_LEN 1000 // 自定义比较函数:按字符串长度升序排序 int compareByLength(const void *a, const void *b) { const char *str1 = *(const char **)a; const char *str2 = *(const char **)b; // 若需排除换行符长度,可先处理每行末尾的\n int len1 = strlen(str1); int len2 = strlen(str2); return len1 - len2; } int main(void) { char data[MAX_LINES][MAX_LEN]; FILE* fread = fopen("C:\\Users\\EXAMPLE\\desktop\\input.txt", "r"); if (fread == NULL) { printf("ERROR\n"); return 1; } int lineCount = 0; // 优化读取逻辑:直接用fgets返回值判断,避免feof陷阱 while (fgets(data[lineCount], MAX_LEN, fread) != NULL && lineCount < MAX_LINES) { // 可选:移除每行末尾的换行符 size_t len = strlen(data[lineCount]); if (len > 0 && data[lineCount][len - 1] == '\n') { data[lineCount][len - 1] = '\0'; } lineCount++; } fclose(fread); // 将二维数组转为指针数组,适配qsort参数要求 char *lines[MAX_LINES]; for (int i = 0; i < lineCount; i++) { lines[i] = data[i]; } qsort(lines, lineCount, sizeof(char*), compareByLength); // 打印排序结果 printf("按行长度升序排序结果:\n"); for (int i = 0; i < lineCount; i++) { printf("%s\n", lines[i]); } return 0; }
关键说明
- 自定义比较函数:
compareByLength通过strlen获取两行长度,返回长度差值,qsort会根据差值完成升序排序(返回负数则前一行排前面,正数则后一行排前面)。 - 换行符处理:如果不需要将换行符计入行长度,可在读取后移除每行末尾的
\n。 - qsort适配:二维char数组无法直接传入
qsort,需转为指针数组lines,每个元素指向二维数组的一行。 - 读取逻辑优化:直接用
fgets返回值判断读取状态,避免feof的常见问题(feof仅在读取到文件末尾后才置位,可能导致多读取一次无效行)。
排序结果示例
按长度升序排序后,输出顺序为:
4. altair 6. Cranium 3. Frozen Styx 1. hello world 5. John Doe and Jane Doe 2. john Jones at Brook Mountains
内容的提问来源于stack exchange,提问作者JohnDoe12
相关产品推荐
相关产品推荐

