Извлечение таймингов из многомерного массива и запись в файл в c - PullRequest
0 голосов
/ 04 декабря 2009

У меня проблемы с извлечением таймингов из файла .srt (субтитры) и записью его в другой файл с именем output.srt. Когда я запускаю следующее, я получаю некоторые вещи, записанные в выходной файл.

// где hr = часы, mn = минуты, sc = секунды, мс = мили секунды

#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 таймингов?

Ответы [ 3 ]

1 голос
/ 04 декабря 2009

Если это в 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;
}
0 голосов
/ 04 декабря 2009

Вам необходимо проверить возвращаемое значение из 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.

Только некоторые из этих строк вернут 8 из sscanf () в качестве количества совпадений, так что проверьте это. Конечно, это не удастся, если текстовая строка также соответствует этому!

Лучше было бы искать пустую строку (кроме первой), затем целое число в одной строке, а затем время. Матч только если все три работают.

0 голосов
/ 04 декабря 2009

Первое, что я заметил, это то, что вы не проверяете результат sscanf (). Вы должны проверить код возврата, чтобы убедиться, что все восемь элементов были отсканированы, и только sprintf () к таймингу [], если данные были отсканированы правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...