user15130479
user15130479

Reputation:

How to scan strings from a text file with delimiter and then display it?

So i tried to make a program that will scan strings from a text file and then display it using loop. But, somehow my program cannot work and it is display weird symbols.. i am new to text file and i would appreciate a lot if someone can explain to me what is wrong with my code.

My code :

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

int main()
{
    FILE *fPtr;
    fPtr = fopen("alumni.txt", "r");
    if (fPtr == NULL) {
        printf("There is a error opening the file.");
        exit(-1);
    }
   
    char name[20], design[50], category[20], location[20];
    
    while (fscanf(fPtr, "%s:%[^\n]:%[^\n]:%[^\n]", &name, &design, &category, &location) != EOF) {
        printf("Name : %s\n", name);
        printf("Designation : %s\n", design);
        printf("Category : %s\n", category);
        printf("Location : %s\n", location);
    }
}

and this is my text file,

Shanie:Programmer:Full Time:Kuala Lumpur
Andy:Sales Agent:Part Time:Johor Bahru
Elaine:Database Administrator Full Time Melaka
Stephanie:MIS manager:Full Time:Penang

Upvotes: 0

Views: 725

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409166

You have two problems: The first is that %s will read space delimited "words", it won't stop at the :. The second problem is that the format %[^\n] reads all until newline.

So you need a scanset format for the first name as well as tell it to read until the next :, which is done with the format %[^:].

So please change to:

while (fscanf(fPtr, " %19[^:]:%49[^:]:%19[^:]:%19[^\n]", name, design, category, location) == 4) {
    ...
}

Please note a couple of other changes I made to your call and loop condition: First of all, I have added length specifiers to the formats, so fscanf will not write out of bounds of your arrays.

Secondly both the %s and %[] formats expects a char * argument, while you provided a pointer to arrays (&name will be of type char (*)[20] not char *). Arrays naturally decay to pointers to their first element, so e.g. name will decay to &name[0] which will be of the correct type char *.

Thirdly I changed the comparison to compare against 4, which is what fscanf will return if it successfully parsed the input.

Lastly I added a space before the first format, to skip any leading space (like the newline from the previous line).


To be sure to be able to continue even in the case of malformed input, I recommend you read full lines instead (using e.g. fgets), and then possibly use sscanf to parse each line.

Upvotes: 2

Related Questions