Search code examples
cfilesearchio

Trying to search a random access file using a string


I can search a random access file without any issues but the problem is I don't understand how it actually works.

Previously i searched a random access file using the method

 FILE fpnt = fopen(FILE_NAME, "rb+");

 User tempUser = {"", "", 0, "", 0};
 printf("Enter the id number of the user to find\n");
 scanf("%d", idNum);
 fseek(fpnt, (idNum - )* sizeof(User), SEEK_SET);
 fread(&tempUser, sizeof(User), 1, fpnt) != EOF && found == 0;

I don't understand how this always finds the correct user when ass the offset isn't always necessarily the same as the ID i would assume. But the problem lies with when I'm trying to access files by using data other than integers.

for example, I'm trying to find users by their names which are strings. the method I use is the following:

 typedef enum tUserLevel {
     MANAGER = 1,
     CLERK = 0,
     NOTFOUND = 9001
 }level;


 typedef struct tUser {
     char userName[20];
     char password[20];
     level priviledgeLevel;
 }User;

do {
    fseek(fpnt, offSet * sizeof(User), SEEK_SET);
    if (fread(&tempUser, sizeof(User), 1, fpnt) == EOF)
        endOfFile = EOF;        
    rewind(fpnt);
    offSet++;
} while (endOfFile!=EOF && !strcmp(username, tempUser.userName));

if (endOfFile==EOF&& strcmp(username, tempUser.userName)) {
    printf("The User was not found\n");
    return noUser;

    //return noUser;
}

So what is supposed to happen is the file will check each user for the entered username (that's the variable called username) and compare the two and stop if both are correct. I'm not sure how this is actually looping though or if the offset affects the pointer in the file the way I want. What DOES happen is I'm always getting EOF so that portion of the code always run even after one read. I had 4 test users Is there a better way to search for these files by string so I can read them and edit them in the file or is this the best way and I'm messing it up somewhere?


Solution

  • Your first example is assuming that the file consists of fixed-length User records, arranged by id number, with no gaps. The record for id 1 would be at offset 0, and the record for id N would be at (N - 1) * sizeof(User). If that's what the file actually contains, this is a reasonable assumption.

    The code in the bottom part of your question seems to be suffering from an identity crisis. It can't figure out if records are sequential and ordered by id, or if the file needs to be searched by matching on username. It's an unworkable hybrid of two different lookup methods. You need to pick one method and go with it.

    If the file is ordered by id and contains no gaps (and you're searching by id), you don't need to search in a while loop.

    On the other hand, if the file is either unordered, or contains gaps, then it is necessary to search. In that case, then the fseek and rewind calls are not needed. Just start from the beginning of the file and read every record sequentially, one at a time, until you find the one matching the requested username.

    Also, comparing the return value of fread with EOF is wrong. The fread function returns the number of items actually read. If the returned number is not equal to the number of items you specified in the call, then either there was a read error, or you've hit the end of file. The EOF constant is intended for use with functions like fgetc that return character values.