views:

61

answers:

3

Hello, I'm having trouble extracting the timings from a .srt (subtitle) file and writing it to another file called output.srt. When i run the following i get some funky stuff written onto the output file.

// where 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;
}

how do I go about extracting those first 10 timings?

A: 

The first thing I notice is that you're not checking the result of the sscanf(). You should check the return code to make sure all eight items were scanned in, and only sprintf() to timings[] if the data was scanned correctly.

Rob Jones
A: 

You need to check the return value from sscanf() to see if the line matched. I downloaded your sample file:

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.

Only some of these lines will return 8 from sscanf() as the number of matches, so test for that. Of course, this will fail if text line matches that, too!

Better would be to look for a blank line (except for the first), then an integer on one line, then the timing. Match only if all three work.

UncleO
+1  A: 

If this is on windows (or MSDOS) the open modes need to be text:

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

Secondly, the code isn't doing anything to react to the differently formatted lines. The first few data lines are:

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.

So, naturally, the first sscanf isn't going to fill in most of the fields. Here's the output I got (for the corresponding lines):

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

To fix this, you'll have to add logic which expects the proper number of elements, or at least reacts to them:

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
}

Edited to add a fixed version of your last edit:

#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;
}
wallyk
I fixed it with what you suggested (edited code^) but I'm still getting the same sort of thing in the output.
sil3nt
thank you so much!:)
sil3nt