2017-02-09 2 views
-1

У меня есть входной файл, содержащие строки следующего формата:C fscanf входного формата

%s %d %d %d %lf %lf ... %lf\n 

где число double значений неизвестно, но для моих расчетов Я принимаю только первых 15 из них.

Проблема, которую я не могу понять, когда я добираюсь до линии, как это:

City0 28 2 2016 1 2 3 4 5 6 7 8 9 10 
City1 28 2 2016 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
City2 1 3 2016 1 2 3 4 5 

и я правильно назначить соответствующие значения в определенную структуру, я получаю следующее:

City0 28 2 2016 Number of measures: 10 
City1 28 2 2016 Number of measures: 15 
16 17 18 19 Number of measures: 1 
City2 1 3 2016 Number of measures: 5 

Как читать (никуда)/игнорировать все, пока не дойду до конца строки, а затем начну читать следующую строку, как обычно? Мне нужен следующий вывод:

City0 28 2 2016 Number of measures: 10 
City1 28 2 2016 Number of measures: 15 
City2 1 3 2016 Number of measures: 5 

Я попробовал это, но не получил больше никаких идей:

i=0; char character; 
while (fscanf(fp, "%s %d %d %d", c.name, &c[i].date.day, 
    &c[i].date.month, &c[i].date.year)==4 && i<number_of_cities) { 
    while (fscanf(fp, "%lf", &c[i].measures[j])==1 && j<15) { 
     j++; 
    } 
    if (j==15) { 
     while (fscanf(fp, "%s", character)!='\n') {} 
    } 
    c[i].mnum = j; 
    j=0; 
    i++; 
} 
+0

это с или с ++? Пожалуйста, предоставьте [mcve] – user463035818

+0

. Он говорит, что C в заголовке и минимальный проверенный пример предоставляется в конце. – tyr

+0

то, что подходит для C++-тега? – user463035818

ответ

2

Вы можете использовать fscanf() прочитать в целой строке ввода, используйте sscanf() для сканирования первые четыре значения и снова использовать sscanf() в цикле для чтения значений double. Трюк здесь заключается в том, чтобы использовать директиву %n, чтобы сохранить положение следующего места чтения в строке.

Вот пример. Обратите внимание, что для индексов массива используется size_t, так как это целочисленный тип без знака, который гарантированно удерживает любой индекс массива. Также обратите внимание, что при открытии файла есть некоторая проверка ошибок и при сканировании начала строки. Если исходные элементы строки не соответствуют ожидаемым значениям, программа выходит с сообщением об ошибке. Эта проверка ошибок может немного затянуться; например, если год вводится как значение с плавающей запятой, например 2016.0, вход будет принят, но значения, хранящиеся в measures[], начинаются с 0 после десятичной точки.

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

struct Data { 
    char name[1000]; 
    struct { 
     int day; 
     int month; 
     int year; 
    } date; 
    size_t mnum; 
    double measures[15]; 
}; 

int main(void) 
{ 
    size_t i = 0, j = 0; 
    char buffer[1000]; 
    char *read_ptr = buffer; 
    int n_read = 0; 

    size_t number_of_cities = 3; 

    struct Data c[number_of_cities]; 

    FILE *fp; 
    if ((fp = fopen("datafile.txt", "r")) == NULL) { 
     fprintf(stderr, "Unable to open file\n"); 
     exit(EXIT_FAILURE); 
    } 

    while (fgets(buffer, 1000, fp) != NULL) { 
     if (sscanf(buffer, "%s %d %d %d %n", c[i].name, &c[i].date.day, 
        &c[i].date.month, &c[i].date.year, &n_read) != 4) { 
      fprintf(stderr, "Incorrect input format\n"); 
      exit(EXIT_FAILURE); 
     } 
     read_ptr += n_read; 
     while (sscanf(read_ptr, "%lf %n", &c[i].measures[j], &n_read) == 1 && 
       j < 15) { 
      read_ptr += n_read; 
      ++j; 
     } 
     c[i].mnum = j; 
     ++i;   
     j = 0; 
     read_ptr = buffer; 
     if (i == number_of_cities) { 
      break; 
     } 
    } 

    for (i = 0; i < number_of_cities; i++) { 
     printf("%s %d %d %d Number of measures: %zu\n", 
       c[i].name, 
       c[i].date.day, c[i].date.month, c[i].date.year, 
       c[i].mnum); 
     for (j = 0; j < c[i].mnum; j++) { 
      printf("%5g", c[i].measures[j]); 
     } 
     putchar('\n'); 
    } 

    return 0; 
} 

Вывод программы, используя ваши данные примера в качестве входных данных:

City0 28 2 2016 Number of measures: 10 
    1 2 3 4 5 6 7 8 9 10 
City1 28 2 2016 Number of measures: 15 
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
City2 1 3 2016 Number of measures: 5 
    1 2 3 4 5 
Смежные вопросы