1

I'm trying to read a file "data.txt" with a single line "00:612:33188" (each number represents a field of data, "changes:size:permission"), and write that information into a struct. I want to write the code in general for any number of characters in those fields.

My question is regarding the use of fscanf. I cannot seem to make it work. The following code produces a segmentation fault error.

#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;
}
3
  • What are the 99's for? Commented Feb 2, 2019 at 17:01
  • 1
    The reason for SIGSEGV is very likely this: stackoverflow.com/a/22945807/50617 Commented Feb 2, 2019 at 17:13
  • @nicomp Because of how I thought fscanf worked. FIELDMAX is 100, I thought in the 100th place fscan would write a '\0' Commented Feb 3, 2019 at 23:10

2 Answers 2

3

The "%s" format reads space delimited strings. If there's no space, it will greedily read as much as it could.

In your case it means that the whole line will be in the changes field, leaving the remaining members uninitialized.

For non-space delimited records you could read the whole line into a string, and then tokenize on the separator.

Sign up to request clarification or add additional context in comments.

1 Comment

Or read as numeric data, then the : would work. You can always convert back to 0-padded strings if wanted.
1

The likely culprit of the segfault is the huge local variable 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 bytes. You get call stack overflow. If you reduce the TOTALELEMENTS to, say, 100, your code works file with my test.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.