0

我无法从.srt(字幕)文件中提取时间并将其写入另一个名为 output.srt 的文件。当我运行以下命令时,我会在输出文件中写入一些时髦的东西。

// 其中 hr=hours,mn=minutes,sc=seconds,ms=mili seconds

#include <stdio.h>
#define LINES 50
#define CHARAC 80
int main(void){
    FILE *in;
    FILE *out;
    char text[LINES][CHARAC];
    char timings[LINES][CHARAC];
    int i=0,lines=0,items=0;
    int hr=0,mn=0,sc=0,ms=0,hr2=0,mn2=0,sc2=0,ms2=0;

    in=fopen("file2.srt","r");
    out=fopen("output.srt","w");

    while (!feof(in)){
        fgets(text[i],80,in);
        items=sscanf(text[i],"%d:%d:%d,%d --> %d:%d:%d,%d ",&hr,&mn,&sc,&ms,&hr2,&mn2,&sc2,&ms2);
        //------------------------------------->edited<----------------------------------
        switch (items)
        {   
            case 1: break;
            case 8: 
                sprintf(timings[i],"%d:%d:%d,%d --> %d:%d:%d,%d",hr,mn,sc,ms,hr2,mn2,sc2,ms2);
                break;
            case 0: break;

        }
        //------------------------------------->edited<----------------------------------
        ++i;
    }
    lines=i;

    for (int i=0;i<lines;i++){
        fprintf(out,"%s\n",timings[i]);
    }

    fclose(in);
    fclose(out);

    return 0;
}

我该如何提取前 10 个时间?

4

3 回答 3

1

如果这是在 Windows(或 MSDOS)上,则打开模式需要是文本:

in =  fopen ("file2.srt", "rt");
out = fopen ("output.srt", "wt");

其次,代码没有对不同格式的行做出任何反应。前几行数据是:

1
00:00:30,909--> 00:00:32,775
Take a look at yourself.

2
00:00:34,066--> 00:00:37,681
Disconnect you from the seats,
lift yourself and take a look in the mirror.

所以,很自然,第一个 sscanf 不会填写大部分字段。这是我得到的输出(对应的行):

1:0:0,0 --> 0:0:0,0
0:0:30,909 --> 0:0:32,775
0:0:30,909 --> 0:0:32,775
0:0:30,909 --> 0:0:32,775
2:0:30,909 --> 0:0:32,775

要解决此问题,您必须添加需要适当数量的元素的逻辑,或者至少对它们做出反应:

itms = sscanf(text[i],"%d:%d:%d,%d --> %d:%d:%d,%d ",&hr,&mn,&sc,&ms,&hr2,&mn2,&sc2,&ms2);
switch (itms)
{
case 1:  // the first line
case 8:  // the lines with the times
case 0:  // the text lines
}

编辑以添加您上次编辑的固定版本:

#include <stdio.h>
#define LINES 50
#define CHARAC 80
int main(void){
    FILE *in;
    FILE *out;
    char text[LINES][CHARAC];
    char timings[LINES][CHARAC];
    int i=0,lines=0,items=0;
    int hr=0,mn=0,sc=0,ms=0,hr2=0,mn2=0,sc2=0,ms2=0;

    in=fopen("file2.srt","rt");
    out=fopen("output.srt","wt");

    while (!feof(in))
    {
        if (!fgets(text[i],80,in))
            break;
        items = sscanf(text[i], "%d:%d:%d,%d --> %d:%d:%d,%d ", &hr,&mn,&sc,&ms,&hr2,&mn2,&sc2,&ms2);
        switch (items)
        {       
        case 1: break;
        case 8: 
                sprintf(timings[i],"%d:%d:%d,%d --> %d:%d:%d,%d",hr,mn,sc,ms,hr2,mn2,sc2,ms2);
                ++i;  // advance only when a valid line is seen
                break;
        case 0: break;
        }
    }
    lines=i;

    for (i=0; i<lines; i++){
        fprintf(out,"%s\n",timings[i]);
    }

    fclose(in);
    fclose(out);

    return 0;
}
于 2009-12-04T04:26:52.050 回答
0

我注意到的第一件事是您没有检查 sscanf() 的结果。您应该检查返回代码以确保扫描了所有八个项目,如果数据被正确扫描,则仅 sprintf() 到时间 []。

于 2009-12-04T04:22:04.867 回答
0

您需要检查 sscanf() 的返回值以查看该行是否匹配。我下载了您的示例文件:

1
00:00:30,909--> 00:00:32,775
Take a look at yourself.

2
00:00:34,066--> 00:00:37,681
Disconnect you from the seats,
lift yourself and take a look in the mirror.

只有其中一些行会从 sscanf() 返回 8 作为匹配数,因此请对此进行测试。当然,如果文本行也匹配,这也会失败!

最好先找一个空行(第一行除外),然后在一行上找一个整数,然后是时间。仅当所有三个都有效时才匹配。

于 2009-12-04T04:25:16.637 回答