C语言修改SRT字幕时间报错:无法将char*转为FILE*,求解决方案
问题修复与代码优化
首先解决你遇到的fprintf错误:
你错误地将字符数组line传给了fprintf的第一个参数,fprintf要求第一个参数是文件指针(FILE*),也就是你打开的newfile。如果你想格式化字符串到line数组,应该用sprintf,但这里你需要将修改后的时间写入新文件,所以直接用fprintf(newfile, ...)即可。
除此之外,你的代码还有多处会导致运行错误或逻辑问题,以下是完整的修复点:
scanf取地址错误:scanf("%d", cnt);缺少取地址符,应该改为scanf("%d", &cnt);,否则会引发未定义行为。- 文件重复打开/关闭:每次循环都用
"w"模式打开新文件会清空之前的内容,最终只保留最后一行修改。应该把newfile的打开操作放在循环前,关闭放在循环后。 - 错误使用
scanf解析字符串:从line中解析时间应该用sscanf,而不是scanf(scanf是从标准输入读取)。 - 未处理完整时间行:SRT的时间行包含
开始时间 --> 结束时间两个时间点,你需要同时解析、调整两个时间再写入。 - 时间行判断逻辑错误:原代码的
sscanf判断无法正确识别时间行,应该通过判断是否成功匹配8个参数来确认。 - 拼写错误:
Error openning file中的openning应为opening。 - 未处理小时为负的情况:当调整后小时变为负数时,需要额外处理(示例中简单设为0,可根据需求修改)。
修正后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #define FILENAME_SIZE 1024 struct Response { char responseBody[25]; }; // 复用时间调整逻辑的函数 void adjust_time(int *hours, int *minutes, int *seconds, int *milliseconds, int offset) { *milliseconds += offset; // 处理毫秒进位/借位 while (*milliseconds < 0) { *seconds -= 1; *milliseconds += 1000; } while (*milliseconds > 999) { *seconds += 1; *milliseconds -= 1000; } // 处理秒进位/借位 while (*seconds < 0) { *minutes -= 1; *seconds += 60; } while (*seconds > 59) { *minutes += 1; *seconds -= 60; } // 处理分钟进位/借位 while (*minutes < 0) { *hours -= 1; *minutes += 60; } while (*minutes > 59) { *hours += 1; *minutes -= 60; } // 可选:处理小时为负的情况,这里简单设为0 if (*hours < 0) { *hours = 0; *minutes = 0; *seconds = 0; *milliseconds = 0; } } int main() { struct Response fileError = {"Error opening file.\n"}; struct Response fileSuccess = {"File found!!\n"}; FILE *file; FILE *newfile; int cnt; char filename[FILENAME_SIZE]; char line[256]; printf("File: "); scanf("%s", filename); file = fopen(filename, "r"); if (file == NULL) { printf("%s", fileError.responseBody); return 1; } printf("%s", fileSuccess.responseBody); printf("Enter a number for adding (ms): "); scanf("%d", &cnt); // 提前打开新文件,避免循环中重复打开清空 newfile = fopen("updatedfile.srt", "w"); if (newfile == NULL) { printf("Failed to create new file.\n"); fclose(file); return 1; } while (fgets(line, sizeof(line), file) != NULL) { int h1, m1, s1, ms1; int h2, m2, s2, ms2; // 判断是否是时间行:尝试解析两个时间点 if (sscanf(line, "%d:%d:%d,%d --> %d:%d:%d,%d", &h1, &m1, &s1, &ms1, &h2, &m2, &s2, &ms2) == 8) { // 调整开始时间和结束时间 adjust_time(&h1, &m1, &s1, &ms1, cnt); adjust_time(&h2, &m2, &s2, &ms2, cnt); // 写入调整后的时间行到新文件 fprintf(newfile, "%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\n", h1, m1, s1, ms1, h2, m2, s2, ms2); } else { // 非时间行,直接复制原内容到新文件 fputs(line, newfile); } } // 关闭文件 fclose(file); fclose(newfile); printf("Subtitles updated successfully!\n"); return 0; }
内容的提问来源于stack exchange,提问作者user19344428
相关产品推荐
相关产品推荐

