C语言实现文本文件指定日期定位及后续内容倒序输出问题
问题分析与解决方案
看起来你的代码里有几个关键错误导致运行失败,我来一步步帮你梳理并修正:
一、代码中的核心问题
- 文件打开模式错误:你用了
"w+"模式打开文件,这个模式会清空现有文件内容并重新创建,导致你根本读不到原有的赛事数据。应该使用"r"(只读)或者"r+"(读写)模式。 - 日期处理与类型不匹配:
- 你计算
date的方式有瑕疵:tm_mon是从0开始计数的(1月是0,5月是4),正确的计算应该是(myTime->tm_mday)*1000000 + (myTime->tm_mon +1)*10000 + (myTime->tm_year + 1900),你之前的myTime->tm_mon*10000+10000虽然结果对,但写法不够直观,容易出错。 - 更严重的是:
date是int类型,datesearch是char数组,你用strcmp()比较它们——strcmp()只能用于字符串比较,这里类型完全不匹配,会导致未定义行为。
- 你计算
fscanf用法错误:fscanf(users_info, "%d", datesearch);中,%d需要接收一个int*指针,但你传入了char数组名,这会导致内存写入错误。fseek逻辑错误:你把循环次数i当作字节偏移量传入fseek,但循环次数和字节数完全不是一回事——每行的长度不同,不能用行数来计算字节偏移。- 未初始化变量:
datesearch数组在第一次strcmp时是未初始化的,这会导致不可预测的结果。
二、实现需求的正确思路
你的需求是:找到日期为03052018的行,然后包含该行在内倒序输出后续所有内容(也就是从最后一行往回输出到目标行)。
因为要倒序输出,直接用fseek定位后正向读取是做不到的,更可靠的方法是:
- 先把文件中所有行读取到内存的动态数组中(如果文件不大的话,这种方法最简单);
- 遍历数组找到目标日期的行;
- 从数组末尾开始倒序输出到目标行。
三、修正后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define MAX_LINE_LENGTH 256 #define TARGET_DATE "03052018" // 目标日期,对应03/05/2018 int main() { FILE *file = fopen("TDesporto.txt", "r"); if (!file) { perror("无法打开文件"); return EXIT_FAILURE; } // 动态存储所有行 char **lines = NULL; int line_count = 0; char buffer[MAX_LINE_LENGTH]; // 读取所有行到内存 while (fgets(buffer, MAX_LINE_LENGTH, file) != NULL) { // 为新行分配内存 lines = realloc(lines, (line_count + 1) * sizeof(char*)); if (!lines) { perror("内存分配失败"); // 释放已分配的内存 for (int i = 0; i < line_count; i++) free(lines[i]); fclose(file); return EXIT_FAILURE; } // 复制行内容(保留原换行符) lines[line_count] = malloc(strlen(buffer) + 1); strcpy(lines[line_count], buffer); line_count++; } fclose(file); // 查找目标日期的行索引 int target_index = -1; for (int i = 0; i < line_count; i++) { // 每行前8个字符是ddmmyyyy格式的日期 if (strncmp(lines[i], TARGET_DATE, 8) == 0) { target_index = i; break; } } if (target_index == -1) { printf("未找到目标日期%s的记录\n", TARGET_DATE); } else { // 倒序输出从最后一行到目标行 printf("倒序输出目标日期及后续内容:\n"); for (int i = line_count - 1; i >= target_index; i--) { printf("%s", lines[i]); } } // 释放内存 for (int i = 0; i < line_count; i++) { free(lines[i]); } free(lines); return EXIT_SUCCESS; }
四、代码说明
- 文件读取:用
fgets逐行读取,存储到动态分配的字符串数组中,彻底避开了fseek的字节偏移问题; - 目标日期查找:用
strncmp比较每行前8个字符(因为ddmmyyyy是8位),精准定位目标行; - 倒序输出:从数组最后一个元素开始,一直输出到目标行的索引位置;
- 内存管理:使用
realloc和malloc动态分配内存,最后记得释放,避免内存泄漏; - 错误处理:添加了文件打开失败、内存分配失败的错误提示,让程序更健壮。
如果你需要处理超大文件(无法全部读到内存),可以改用另一种方法:先遍历文件一次,记录每个行的起始字节偏移量,然后从最后一个偏移开始倒序读取每行,直到目标行的偏移位置。不过对于普通的赛事数据文件,上面的方法已经足够高效。
内容的提问来源于stack exchange,提问作者hanuruh
相关产品推荐
相关产品推荐

