Чтение определенных фраз из входного файла в C

Последний вопрос на ночь. Я стараюсь не публиковать более одного раза за борьбу, ха-ха...

Этот немного проще.

У меня есть текстовый файл с серией упорядоченных чисел в первых 8 строках. Каждая строка после — это определенная фраза, такая как «КУПИТЬ ПРЕДМЕТ» или «ПОЗИЦИОННЫЙ ПРЕДМЕТ», за которой следует целое число (есть несколько фраз, но меня интересует только одна). По сути, я пытаюсь создать цикл for или while, в котором я могу обнаружить фразу в документе, установить указатель на конец фразы, а затем выполнить fscanf целое число справа от фразы. Единственная проблема, с которой я сталкиваюсь, - это получить указатель на конец конкретной фразы, а затем прочитать число. А также то, что фраза повторяется на разных строках и я не хочу, чтобы значения брались все сразу.

Я уверен, что могу сделать простой

while (!feof(//function for reading phrase)) {
      fscanf("%d", &value);
      //rest of function

И это было бы так. Но я пробовал fseek и fget, и ничто действительно не могло помочь получить указатель на место, которое мне нужно, без предустановленного места, куда идти. Входной файл каждый раз будет разным, поэтому я не могу просто сказать, чтобы он опускался на 1024 пробела или что-то в этом роде. Просто не знаю, как бы вы вообще пошли на это...

Также ниже приведен пример входного файла.

75 75 908
10 10
18 23.10 10.09
70 5 15
8 100 20 28.99
30 40 50 60
4 6 8 8 5 5 5 6 7 10
10
BUY ITEM 8
BUY ITEM 10
AWARD ITEM 7
BUY ITEM 1
BUY ITEM 3
AWARD ITEM 9
BUY ITEM 7
RETURN ITEM 8

Большая признательность за чью-либо помощь.


person Darksider13    schedule 27.09.2014    source источник
comment
При отсутствии указанного формата файла вам придется читать каждую строку, пока не найдете ее. Это не сложнее, чем это. Вместо того, чтобы устанавливать указатель и затем читать число, просто прочитайте всю строку и извлеките из нее свои числа, если вы получите совпадение.   -  person Crowman    schedule 27.09.2014
comment
И как мне прочитать каждую строку, а затем извлечь число, если я получу совпадение? Это звучит как сделка с fseek, верно?   -  person Darksider13    schedule 27.09.2014
comment
Нет, используйте fgets(), чтобы получить всю строку, а затем либо fscanf(), либо strtol(), либо что-то в этом роде, чтобы получить номер. Если ваш файл всегда соответствует этому формату, и вы знаете, что ваша строка начинается, например, с BUY ITEM, за которым следует пробел, то вы будете знать, что ваш номер начинается с 10-го символа строки.   -  person Crowman    schedule 27.09.2014
comment
Потрясающе, большое спасибо.   -  person Darksider13    schedule 27.09.2014


Ответы (1)


Вот простой способ сделать это, используя тот факт, что в рассматриваемых строках, если ваш файл соответствует одному и тому же формату, числа всегда будут отображаться в одном и том же символе строки. Это немного хрупко, и было бы лучше сделать вашу программу более надежной, например, чтобы справляться с произвольным количеством пробелов, но я оставлю это вам в качестве упражнения:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_LEN 100
#define BUY_LEN 9
#define AWARD_LEN 11

int main(void) {
    FILE * infile = fopen("file.dat", "r");
    if ( !infile ) {
        perror("couldn't open file");
        return EXIT_FAILURE;
    }

    char buffer[MAX_LEN];
    char * endptr;

    while ( fgets(buffer, MAX_LEN, infile) ) {
        if ( !strncmp(buffer, "BUY ITEM ", BUY_LEN ) ) {
            char * num_start = buffer + BUY_LEN;
            long item = strtol(num_start, &endptr, 0);

            if ( endptr == num_start ) {
                fprintf(stderr, "Badly formed input line: %s\n", buffer);
                return EXIT_FAILURE;
            }

            printf("Bought item %ld\n", item);
        }
        else if ( !strncmp(buffer, "AWARD ITEM ", AWARD_LEN) ) {
            char * num_start = buffer + AWARD_LEN;
            long item = strtol(num_start, &endptr, 0);

            if ( endptr == num_start ) {
                fprintf(stderr, "Badly formed input line: %s\n", buffer);
                return EXIT_FAILURE;
            }

            printf("Awarded item %ld\n", item);
        }
    }

    fclose(infile);
    return 0;
}

Запустив это с образцом файла данных в вашем вопросе, вы получите:

paul@local:~/src/sandbox$ ./extr
Bought item 8
Bought item 10
Awarded item 7
Bought item 1
Bought item 3
Awarded item 9
Bought item 7
paul@local:~/src/sandbox$ 

Кстати, основываясь на одном из предложений в вашем вопросе, вы можете проверить ответы на вопрос "while( !feof( file ) )" всегда неправильно.

person Crowman    schedule 27.09.2014