Search code examples
cfiletcc

How to read a flat file and put the data to corresponding variable


I have a flat file (txt file), containing some field:

Primary key, Name, Address, Salary -separated by | like:

A0001|John|New York City|12000
A0002|Daisy|New Delhi|32000
A0003|Dany|London|23000

.. etc

How could I develop a code to search each data in flat file when I have its primary key? And each data of it is stored to particular variable for next purpose.

The result I want is:

Input the primary key: A0002

Result:
Name = Daisy
Address = New Delhi
Salary = 32000

Input the primary key: 

Solution

  • Let's start with a very basic approach that uses the flat-file for your storage and on each query, loops over the flat file attempting to match your key against the first field. If a match is found, simply use sscanf to separate the values (ignoring the 1st field using the assignment suppression modifier to your sscanf conversion specifier for that field, e.g. the '*'). Print the values. If the key isn't found in the file, say so as well.

    Using fgets() for input, you can simply take input until the user presses Enter on a blank line for the key. (you simply check if the 1st character is '\n' and if so, break the loop).

    You loop continually to allow multiple key queries to be made, using rewind() at the beginning of each loop to rewind to the beginning of the file each time.

    Putting that together you could first open and validate your file is open for reading.

    #include <stdio.h>
    #include <string.h>
    
    #define MAXN   64   /* if you need a constand, #define one (or more) */
    #define MAXC 1024   /* (don't skimp on buffer size) */
    
    int main (int argc, char **argv) {
    
        /* use filename provided as 1st argument ("flatfile.txt" by default) */
        FILE *fp = fopen (argc > 1 ? argv[1] : "flatfile.txt", "r");
    
        if (!fp) {  /* validate file open for reading */
            perror ("file open failed");
            return 1;
        }
    

    Now begin your continual loop that will read the key from the user, trim the '\n' from the end of the key (you don't want that as part of the comparison), and get the length of the key:

        for (;;) {  /* loop continually until [Enter] on empty line */
            char buf[MAXC], name[MAXN], city[MAXN], key[MAXN];
            unsigned salary, len, found = 0;
    
            rewind (fp);    /* rewind file to beginning */
            fputs ("\nInput the primary key: ", stdout);    /* prompt for key */
            if (!fgets (key, MAXN, stdin) || *key == '\n')  /* read key */
                break;
            key[strcspn (key, "\n")] = 0;                   /* trim '\n' */
            len = strlen(key);                              /* get key length */
    

    With that information, now loop through your file reading each line into a buffer buf and then use strcmp to compare the first len chars with your key, and if there is a match, print it and set the found flag and break your file read loop. At the end if found isn't set, let the user know the key wasn't found, now do it again until the user presses Enter alone on the line asking for the primary key:

            while (fgets (buf, MAXC, fp)) {                 /* read each line */
                if (strncmp (buf, key, len) == 0) {         /* compare key */
                    /* parse line into separate values, ignoring 1st key field */
                    if (sscanf (buf, "%*63[^|]|%63[^|]|%63[^|]|%u",
                                    name, city, &salary) == 3) {
                        printf ("\nResult:\nName = %s\nAddress = %s\n"
                                "Salary = %u\n", name, city, salary);
                        found = 1;  /* set flag indicating key found */
                        break;      /* no sense in reading rest */
                    }
                }
            }
            if (!found) /* if key not found, so indicate */
                fputs ("\nResult: (not found)\n", stdout);
        }
    

    All that remains is closing the input file. A complete example would be:

    #include <stdio.h>
    #include <string.h>
    
    #define MAXN   64   /* if you need a constand, #define one (or more) */
    #define MAXC 1024   /* (don't skimp on buffer size) */
    
    int main (int argc, char **argv) {
    
        /* use filename provided as 1st argument ("flatfile.txt" by default) */
        FILE *fp = fopen (argc > 1 ? argv[1] : "flatfile.txt", "r");
    
        if (!fp) {  /* validate file open for reading */
            perror ("file open failed");
            return 1;
        }
    
        for (;;) {  /* loop continually until [Enter] on empty line */
            char buf[MAXC], name[MAXN], city[MAXN], key[MAXN];
            unsigned salary, len, found = 0;
    
            rewind (fp);    /* rewind file to beginning */
            fputs ("\nInput the primary key: ", stdout);    /* prompt for key */
            if (!fgets (key, MAXN, stdin) || *key == '\n')  /* read key */
                break;
            key[strcspn (key, "\n")] = 0;                   /* trim '\n' */
            len = strlen(key);                              /* get key length */
    
            while (fgets (buf, MAXC, fp)) {                 /* read each line */
                if (strncmp (buf, key, len) == 0) {         /* compare key */
                    /* parse line into separate values, ignoring 1st key field */
                    if (sscanf (buf, "%*63[^|]|%63[^|]|%63[^|]|%u",
                                    name, city, &salary) == 3) {
                        printf ("\nResult:\nName = %s\nAddress = %s\n"
                                "Salary = %u\n", name, city, salary);
                        found = 1;  /* set flag indicating key found */
                        break;      /* no sense in reading rest */
                    }
                }
            }
            if (!found) /* if key not found, so indicate */
                fputs ("\nResult: (not found)\n", stdout);
        }
        fclose (fp);   /* close file */
    }
    

    Example Input File

    $ cat dat/flatfile.txt
    A0001|John|New York City|12000
    A0002|Daisy|New Delhi|32000
    A0003|Dany|London|23000
    

    Example Use/Output

    $ ./bin/readflatfile dat/flatfile.txt
    
    Input the primary key: A0002
    
    Result:
    Name = Daisy
    Address = New Delhi
    Salary = 32000
    
    Input the primary key: A0003
    
    Result:
    Name = Dany
    Address = London
    Salary = 23000
    
    Input the primary key: A0004
    
    Result: (not found)
    
    Input the primary key:
    

    Look things over and let me know if you have further questions.