0

There is a text file called 1.txt like below that contains certain names, I want to add them to a linked list however the code doesn't scan only one name but the whole line, how can I make fscanf so that it only scans a single name?

Example 1.txt:

ana,bob,max,dolores

My code:

FILE *fp = fopen("1.txt", "rt");
while (!feof(fp)) {
    char name_in[100];
    fscanf(fp, "%s,", name_in);
    printf("%s", name_in);
    addnewnode(head, name_in);
}
fclose(fp);
ATheCoder
  • 958
  • 1
  • 9
  • 20
  • something like [this](http://stackoverflow.com/questions/12911299/read-csv-file-in-c) ? – Zorgatone Jan 13 '17 at 11:39
  • Possible duplicate of [In C, how should I read a text file and print all strings](http://stackoverflow.com/questions/3463426/in-c-how-should-i-read-a-text-file-and-print-all-strings) – kiner_shah Jan 13 '17 at 13:13

2 Answers2

2

The problem is that with the "%s" format, then scanf will not stop scanning until it hit the end of the input or a whitespace. That means you can't use scanf alone to parse your input.

Instead I suggest you read your whole line into a buffer, for example using fgets. Once you have it then you can use strtok in a loop to tokenize the line.


Not using scanf also sidesteps a big problem with your format string: Namely that it will look for a trailing comma in the input. If there's no comma at the end of the line (like in your example) then scanf will just block. It will block until there is a comma, but if you don't give it a comma then it might block forever. Either that or you will not get the last entry because scanf will fail. Checking what scanf returns is crucial.

Also, I strongly suggest you read Why is “while ( !feof (file) )” always wrong?.

Community
  • 1
  • 1
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

What's in a name?

A name is usually thought of as containing letters, maybe spaces and some other characters. Code needs to be told what char make up a name, what are valid delimiters and handle other unexpected char.

"%s" only distinguishes between white-space and non-white-space. It treats , the same as letters.

"%width[A-Za-z' ]" will define a scanset accepting letters, ' and space. It will read/save up to width characters before appending a null character.

Always a good idea to check the return value of a input function before using the populated objects.

FILE *fp = fopen("1.txt", "rt");
if (fp == NULL) Handle_Error();

// end-of-file signal is not raised until after a read attempt.
// while (!feof(fp)) {

char name_in[100];
char delimiter[2];
int count;
while ((count = fscanf(fp, "%99[A-Za-z' ]%1[,\n]", name_in, delimiter)) == 2) {
  printf("<%s>%s", name_in, delimiter);
  addnewnode(head, name_in);
  if (delimiter[0] == '\n') {
    ; // Maybe do something special at end-of-line
  }
}
fclose(fp);

// Loop stopped unexpectedly
if (count != EOF || !feof(fp)) {
  puts("Oops");
}

More robust code would read the line like with fgets() and then process the string. Could use similar code as above but with sscanf()


To include - in a scanset so code can handle hyphenated names, list it first. You may want to allow other characters too.

"%width[-A-Za-z' .]"

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256