Как использовать fscanf здесь, чтобы записать в переменную из файла? - PullRequest
0 голосов
/ 02 февраля 2019

Я пытаюсь прочитать файл «data.txt» с одной строкой «00: 612: 33188» (каждое число представляет поле данных «changes: size :missions») и записать эту информацию вструктура.Я хочу написать код для любого количества символов в этих полях.

Мой вопрос касается использования fscanf.Я не могу заставить его работать.Следующий код выдает ошибку ошибки сегментации.

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

#define MAXHITS 50
#define FIELDMAX 100
#define TOTALELEMENTS 100000

typedef struct Elements{
  char changes[FIELDMAX];
  char size[FIELDMAX];
  char permission[FIELDMAX];
} Elements;

int main(int argc, char const *argv[]) {
  if(argc < 2) {
       printf("\nSyntax: fscanf data\n\n");
       exit(EXIT_FAILURE);
  }

  Elements total[TOTALELEMENTS];
  Elements hits[MAXHITS];
  int total_elements = 0;
  int total_hits = 0;
  FILE *fp;

  // open the file and scan each field copying to the corresponding struct
  fp = fopen (argv[1], "r");

  if (fp){

    fscanf(fp,"%99s:%99s:%99s", total[total_elements].changes,
    total[total_elements].size, total[total_elements].permission);

    printf("%s\n%s\n%s\n", total[total_elements].changes,
    total[total_elements].size, total[total_elements].permission);

    fclose (fp);
  }

  return 0;
}

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

Вероятным виновником segfault является огромная локальная переменная total

#define MAXHITS 50
#define FIELDMAX 100
#define TOTALELEMENTS 100000

typedef struct Elements{
  char changes[FIELDMAX];
  char size[FIELDMAX];
  char permission[FIELDMAX];
} Elements;

int main () {
...
  Elements total[TOTALELEMENTS];
}

100000 * 300 байт.Вы получаете переполнение стека вызовов.Если вы уменьшите TOTALELEMENTS, скажем, до 100, ваш код будет работать с моим тестом.

0 голосов
/ 02 февраля 2019

Формат "%s" читает строки с разделителями .Если пробела нет, он будет жадно читать столько, сколько мог.

В вашем случае это означает, что вся строка будет находиться в поле changes, оставляя остальные элементы неинициализированными.

Для записей без пробелов вы можете прочитать всю строку в строку, а затем маркировать в разделителе.

...