0

I have this program in C and I'm trying to get strings from a file and put them in a array. It works perfectly for reading the file, but seems it messes up with the assign in the array.

    int getUsers(){
    char userVect[5][25];
    char user[24];
    int i = 0, j = 0, k;

    FILE  *usernames;
    usernames = fopen("usernames.cfg", "r");
    if (usernames == NULL){
        perror("usernames - err");
        return(-1);
    }
    while(!feof(usernames)){
        fgets(user, sizeof(user), usernames);
        strcpy(userVect[j], user);
        j++;
    }

    fclose(usernames);
    for(k=0; k<j; k++)
        printf("Usernames are:  %s\n", userVect[j]);

    return 0;
}

It's surely from the user variable, or from the strcpy function, but not sure what. Thx.

Justplayit94
  • 385
  • 2
  • 19
  • 2
    http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong – Martin James Oct 31 '15 at 22:00
  • 1
    See [`while (!feof(file))` is always wrong](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) — which is what Martin linked to, but including the title makes it clearer. – Jonathan Leffler Oct 31 '15 at 22:04
  • 1
    It "seems" to mess up the array, or it does? If so, how? Please use [edit] - a question should contain all relevant information. – Jongware Oct 31 '15 at 22:04
  • 1
    As long as you fix the `while (!feof(usernames))` condition, and as there are no more than 5 entries in the `usernames.cfg` file, and as long as none of the names is more than 23 characters long, and as long as nothing outside this function needs to access the user names, then what you've got looks OK (though you might want to eliminate the newlines from the names). You should protect against overflow by testing `j` against the upper bound (`5`). Your output will be double-spaced. What's the problem you're running into? – Jonathan Leffler Oct 31 '15 at 22:08
  • If i print the array, it just shows garbage. I only have 3 usernames, but they are separated by newlines. – Justplayit94 Oct 31 '15 at 22:10
  • How should I fix the while condition? – Justplayit94 Oct 31 '15 at 22:12

3 Answers3

1

See Why is “while ( !feof (file) )” always wrong?.

Here's my suggestion to avoid the problems associated with using while (!feof(username)).

fgets return NULL if it is unable to read any data. The conditional of the while loop can be modified to use that value.

while(fgets(user, sizeof(user), usernames) != NULL){
    strcpy(userVect[j], user);
    j++;
}

Rest of your code is OK as long as there are 5 or less lines in the input file. You can make it more robust by adding another check.

while( j < 5 && fgets(user, sizeof(user), usernames) != NULL ){
    strcpy(userVect[j], user);
    j++;
}

You need to also fix the printf line to use k instead of j.

printf("Usernames are:  %s\n", userVect[k]); // Use k, not j.
Community
  • 1
  • 1
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • with the while change it still shows something like : Usernames are: �� Usernames are: �� Usernames are: �� – Justplayit94 Oct 31 '15 at 22:20
  • Oh yeah, forgot and didn't even saw that. Damn, thanks – Justplayit94 Oct 31 '15 at 22:26
  • And if now I want to return this array, is it possible to have a variable type char user[5] take the values from array, or is it another way? – Justplayit94 Oct 31 '15 at 22:31
  • @Justplayit94, that is an unrelated question. It'll be better to post another question rather than get an answer through comments. Questions and answers are in the searchable database in SO. I don't think comments are. – R Sahu Oct 31 '15 at 22:33
1

As mentioned in the comments, you shouldn't use feof. Since fgets will return NULL on error or end-of-file, you can use that for your loop condition.

while(fgets(user, sizeof(user), usernames)) {
    strcpy(userVect[j], user);
    j++;
}

The other problem is here:

for(k=0; k<j; k++)
    printf("Usernames are:  %s\n", userVect[j]);

Your loop variable is k, but you're using j instead. That's why you're seeing garbage output.

for(k=0; k<j; k++)
    printf("Usernames are:  %s\n", userVect[k]);
Community
  • 1
  • 1
dbush
  • 205,898
  • 23
  • 218
  • 273
0

Beside the trouble with feof and the limit of 5 users not taken into account there are many other issues with the program shown as exemple:

fgets won't correctly read lines if there are more than 24 characters (size of your username before). Lines of more than 24 characters will be treated as multiple usernames. Very unlikey what is intended. This should be taken into account, for instance explicitely truncating username after reading the end of line.

If the line is less than 24 characters the username will contain the \n line terminator. Which is also unlikely to be intended. The line terminator should probably be striped as it is not part of the name. If a line is empty you'll get an empty name with a trailing '\n'.

In the final printing loop, you should access names in userVect using loop index k, not j as written, or you won't see much: only the next to last name repeated multiple times, which is uninitialised stack memory. It could be litterally anything.

Not much to fix, but it should fix what you see.

kriss
  • 23,497
  • 17
  • 97
  • 116