2015-10-31 5 views
0

У меня есть эта программа в C, и я пытаюсь получить строки из файла и поместить их в массив. Он отлично работает для чтения файла, но кажется, что это беспорядок с назначением в массиве.C строки чтения

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; 
} 

Это, безусловно, из пользовательской переменной или из функции strcpy, но не уверен, что. Thx.

+2

http: // stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong –

+1

См. ['while (! feof (файл))' всегда ошибочно] (http://stackoverflow.com/questions/5431941/while -feof-file-is-always-wrong) - это то, к чему привязался Мартин, но включая заголовок делает его более ясным. –

+1

«Кажется» испортить массив, или он делает? Если да, то как? Используйте [edit] - вопрос должен содержать всю соответствующую информацию. – usr2564301

ответ

0

Помимо проблем с feof и лимитом 5 пользователей не учитывается есть много других проблем, с программой, показанной в Exemple:

fgets не будет правильно читать строки, если есть более 24 символа (размер вашего имени пользователя раньше). Строки из более чем 24 символов будут обрабатываться как несколько имен пользователей. Очень не нравится то, что предназначено. Это следует учитывать, например, явно усекать имя пользователя после прочтения конца строки.

Если строка меньше 24 символов, имя пользователя будет содержать терминатор линии \n. Что также вряд ли будет предназначено. Терминатор линии должен, вероятно, быть полосатым, поскольку он не является частью имени. Если строка пуста, вы получите пустое имя с завершающим «\ n».

В конечном цикле печати вам необходимо получить доступ к именам в userVect, используя индекс цикла k, а не j как написанный, или вы не увидите много: повторное повторение несколько раз повторяется несколько раз, что является неинициализированной суммой стека. Это может быть ликтериально что угодно.

Не так много, чтобы исправить, но он должен исправить то, что вы видите.

1

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

Это мое предложение, чтобы избежать проблем, связанных с использованием while (!feof(username)).

fgets return NULL, если он не может прочитать данные. Условие использования цикла while может быть изменено для использования этого значения.

Остальная часть кода в порядке, если в входном файле имеется 5 или менее строк. Вы можете сделать его более надежным, добавив еще одну проверку.

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

Вы должны также зафиксировать printf линию использовать k вместо j.

printf("Usernames are: %s\n", userVect[k]); // Use k, not j. 
+0

с изменением он все еще показывает что-то вроде: Имя пользователя: Имя пользователя: Имена пользователей: – Justplayit94

+0

О да, забыл и даже не видел этого. Damn, thanks – Justplayit94

+0

И если теперь я хочу вернуть этот массив, возможно ли иметь тип переменной char user [5] взять значения из массива, или это по-другому? – Justplayit94

1

Как упоминалось в комментариях, you shouldn't use feof. Поскольку fgets вернет NULL по ошибке или в конец файла, вы можете использовать это для своего условия цикла.

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

Другая проблема здесь:

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

Ваша переменная цикла является k, но вы используете j вместо этого. Вот почему вы видите выход мусора.

for(k=0; k<j; k++) 
    printf("Usernames are: %s\n", userVect[k]); 
Смежные вопросы