如何在这里使用fscanf从文件写入变量?

时间:2019-02-02 16:59:28

标签: c stream segmentation-fault scanf

我正在尝试读取一行“ 00:612:33188”(每个数字代表一个数据字段,“ changes:size:permission”)的文件“ data.txt”,并将该信息写入一个结构。我想为这些字段中的任意数量的字符编写代码。

我的问题是关于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 :(得分:3)

"%s"格式读取以空格分隔的字符串。如果没有空间,它将尽可能贪婪地阅读。

在您的情况下,这意味着整行将位于changes字段中,而其余成员未初始化。

对于非空格分隔的记录,您可以将整行读取为一个字符串,然后在分隔符上tokenize

答案 1 :(得分:1)

的段错误的可能的罪魁祸首是巨大的局部变量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,则您的代码在我的测试中起作用。