C语言读取文件时间戳转长整型及计算与2000年秒差问题
问题修复与代码优化
核心错误分析
类型不匹配错误
编译警告initialization of 'char' from 'char *' makes integer from pointer without a cast来自这行代码:char timestamp = ("%s", *strings);*strings等价于strings[0][0],是单个字符而非字符串指针- 你试图把字符串赋值给单个
char变量,类型完全不匹配,且逗号表达式写法无意义
未遍历文件内容
代码仅错误处理了第一个时间戳,随后将同一结果重复写入输出文件,未循环处理所有读取到的时间戳字符串。时间计算逻辑错误
通过拼接数字再拆分的方式计算时间差,忽略了闰年、月份天数差异,结果必然不准确,应使用C标准库的tm结构体和mktime函数处理时间转换。冗余内存分配
p = (char *) malloc (num_strings + 1);分配的内存从未使用,属于无效代码。
修正后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define MAX_FILENAME_LEN 256 #define MAX_STRINGS 100 #define MAX_LENGTH 50 // 将dd/mm/yyyy-hh:mm:ss格式的字符串转换为秒数(从1970-01-01 00:00:00 UTC开始) time_t timestamp_to_seconds(const char *timestamp) { struct tm tm_time = {0}; // 按格式解析时间字符串到tm结构体 if (sscanf(timestamp, "%d/%d/%d-%d:%d:%d", &tm_time.tm_mday, &tm_time.tm_mon, &tm_time.tm_year, &tm_time.tm_hour, &tm_time.tm_min, &tm_time.tm_sec) != 6) { return -1; // 解析失败 } // tm_mon范围是0-11,需减1 tm_time.tm_mon -= 1; // tm_year是从1900年开始的偏移量,需减1900 tm_time.tm_year -= 1900; // 忽略夏令时 tm_time.tm_isdst = -1; // 转换为秒数 return mktime(&tm_time); } // 计算与2000-01-01 00:00:00的秒数差 long long calculate_diff_from_2000(time_t current_sec) { // 构造2000年1月1日的tm结构体 struct tm tm_2000 = {0}; tm_2000.tm_year = 100; // 2000-1900=100 tm_2000.tm_mon = 0; // 1月对应0 tm_2000.tm_mday = 1; tm_2000.tm_isdst = -1; time_t sec_2000 = mktime(&tm_2000); return current_sec - sec_2000; } int main() { char strings[MAX_STRINGS][MAX_LENGTH]; char input_filename[MAX_FILENAME_LEN]; char output_filename[MAX_FILENAME_LEN]; int num_strings = 0; printf("输入文件名: "); scanf("%s", input_filename); printf("输出文件名: "); scanf("%s", output_filename); // 打开输入文件 FILE *fileptr = fopen(input_filename, "r"); if (fileptr == NULL) { printf("打开输入文件失败!\n"); return 1; } // 读取所有时间戳字符串 while (num_strings < MAX_STRINGS && fgets(strings[num_strings], MAX_LENGTH, fileptr) != NULL) { // 移除换行符 size_t len = strlen(strings[num_strings]); if (len > 0 && strings[num_strings][len - 1] == '\n') { strings[num_strings][len - 1] = '\0'; } num_strings++; } fclose(fileptr); // 打开输出文件 fileptr = fopen(output_filename, "w"); if (fileptr == NULL) { printf("打开输出文件失败!\n"); return 1; } // 遍历每个时间戳,计算并写入结果 for (int i = 0; i < num_strings; i++) { time_t sec = timestamp_to_seconds(strings[i]); if (sec == -1) { fprintf(fileptr, "无效的时间戳: %s\n", strings[i]); continue; } long long diff = calculate_diff_from_2000(sec); fprintf(fileptr, "%lld\n", diff); } fclose(fileptr); return 0; }
关键修改说明
替换时间转换逻辑
- 用
sscanf直接解析时间字符串到tm结构体,避免手动拼接数字的错误 - 借助
mktime将tm结构体转换为标准秒数,自动处理闰年、月份天数差异,计算更准确
- 用
修复遍历逻辑
- 新增循环遍历
strings数组中的每个时间戳,逐个处理并写入结果
- 新增循环遍历
精简冗余代码
- 删除无用的
malloc代码,简化变量结构
- 删除无用的
增加错误处理
- 新增时间戳解析失败的判断,输出错误提示,避免程序异常
测试验证
对于输入29/11/2021-15:33:56,修正后的代码会输出694199036,与预期结果一致。
内容的提问来源于stack exchange,提问作者Ceallaigh
相关产品推荐
相关产品推荐

