0

i have a structure like so:

struct profile {
    char firstName[15], lastName[15];
    int age, phoneNo;
};

and i've written a code to store the text data from this structure into a text file, like so:

int main()
{
    
    FILE* fPtr;
    fPtr = fopen("profile.txt", "a");

    printf("\n\nPlease enter your details:");
    struct profile c;
    printf("\n\nEnter your first name: ");
    gets(c.firstName);
    printf("\nEnter your last name: ");
    gets(c.lastName);
    printf("\nEnter your age: ");
    scanf("%d", &c.age);
    printf("Enter your phone number: ");
    scanf("%d", &c.phoneNo);

    fprintf(fPtr, "%s#%s#%dy#%d#\n", c.firstName, c.lastName, c.age, c.phoneNo);

    fclose(fPtr);

    return 0;
}

the code above will store the data input into the struct into a text file of strings, each string is one profile, and each value is separated by a '#', like below:

John#Doe#35y#0123456789#
Mary Ann#Brown#20y#034352421#
Nicholas#McDonald#15y#0987654321#

i'd like to know if there's a way i can search for a certain name/age/phoneNo from the text file, select the entire string of the corresponding profile and put each value back into a structure as above so that i can display it? i've separate each value with a '#' so that the program can use the # to differentiate between each value when it reads from the file but i'm not sure how i can separate it when i read the data. should i use fgets ? i'm new to C so i'd appreciate it if someone could explain it me how.

cloud
  • 105
  • 9
  • 1
    Never ***ever*** use `gets`. It's so [dangerous](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) it has even been removed from the C language specification. Use e.g. [`fgets`](https://en.cppreference.com/w/c/io/fgets) instead. – Some programmer dude Oct 19 '20 at 03:28
  • As for your problem, you basically have a [comma-separated values](https://en.wikipedia.org/wiki/Comma-separated_values) file, but with `#` instead of `,`. And there's tons of examples and tutorials on how to read and parse such files, if you just search a little. – Some programmer dude Oct 19 '20 at 03:30
  • Just as a side note: It is unsafe to use `scanf` without checking the return value. See this page for further information: [A beginners' guide away from scanf()](http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html) – Andreas Wenzel Oct 19 '20 at 03:47
  • 1
    Yes, you can use `fgets` for reading in one line of data. You can then use either [`strtok`](https://en.cppreference.com/w/c/string/byte/strtok) or [`strchr`](https://en.cppreference.com/w/c/string/byte/strchr) for separating the individual fields of the data. – Andreas Wenzel Oct 19 '20 at 03:51
  • @AndreasWenzel thank you. there's something i'm not sure of, which is if i use fgets when searching for, say, a name, how do i get the entire string of the profile instead of just the name that i'm searching for? e.g. fgets(firstName, 20, fPtr) and printf("%s", firstName) will only get and display the firstName of the record, not the entire profile – cloud Oct 19 '20 at 04:11
  • 1
    @cmy: The function `fgets` will read the entire line, not just the first name. Of course, the size of the buffer must be large enough to hold all data, otherwise it will not read in the entire line. In your case, the number `20` would be too small. This number should of course never be larger than the actual buffer size, otherwise you will cause a [buffer overflow](https://en.wikipedia.org/wiki/Buffer_overflow) (which could cause your program to crash or misbehave in other ways). – Andreas Wenzel Oct 19 '20 at 04:14
  • @AndreasWenzel sorry for bothering. it worked after i modified the code, thank you for the advice! have a nice day! :) – cloud Oct 19 '20 at 05:33
  • @cmy: By the way, [`strtok`](https://en.cppreference.com/w/c/string/byte/strtok) is destructive in the sense that it modifies the contents of the memory buffer by replacing the `'#'`with a null terminator. For this reason, depending on your code, it may be preferable to use [`strchr`](https://en.cppreference.com/w/c/string/byte/strchr) instead, which is not destructive. – Andreas Wenzel Oct 19 '20 at 05:34

1 Answers1

1

This is not exactly what you are looking for , but it helps you start using fgets and how to search for entries(only strings now).

#include <stdio.h>
#include <string.h>
#define MYFILE "profile.txt"
#define BUFFER_SIZE 50

int main()
{
    char nametoSearch[BUFFER_SIZE];
    char Names[BUFFER_SIZE];
    
    FILE* fPtr;
    if (fPtr = fopen(MYFILE, "r"))
    {
        // flag to check whether record found or not
        int fountRecord = 0;
        printf("Enter name to search : ");
        //use fgets if you are reading input with spaces like John Doe
        fgets(nametoSearch, BUFFER_SIZE, stdin);
        //remove the '\n' at the end of string 
        nametoSearch[strlen(nametoSearch)-1] = '\0';
        
        while (fgets(Names, BUFFER_SIZE, fPtr)) 
        {
            // strstr returns start address of substring in case if present
            if(strstr(Names,nametoSearch))
            {
                printf("%s\n", Names);
                fountRecord = 1;
            }
        }
        if ( !fountRecord )
            printf("%s cannot be found\n",nametoSearch);
        
        fclose(fPtr);
    }
    else
    {
        printf("file %s  cannot be opened\n", MYFILE );
    }   
    return 0;
}
IrAM
  • 1,720
  • 5
  • 18