Ошибка ошибки сегментации с использованием strtok() и strcmp()

Я пытаюсь сделать простую программу C, которая проверяет файл паролей Linux по очереди на поиск строки, начинающейся с имени пользователя, предоставленного аргументом командной строки. Каждая строка состоит из нескольких токенов, разделенных двоеточием. Первый токен - это имя пользователя, второе не имеет значения, третий - номер идентификатора пользователя (UID), который нужно распечатать, а 4-й токен - это номер идентификатора группы (GID), который также необходимо распечатать.

Используя несколько тестов на печать и поиск в Интернете решений, я думаю, моя переменная токена остается NULL после назначения ее моему первому вызову strtok (printf токена в этот момент ничего не печатает). Затем токен NULL сравнивается, используя strcmp, с именем пользователя, которое производит ошибку ошибки сегментации. Если мой анализ до сих пор является правильным (что может быть очень не так, поскольку я новичок в C), как я могу избежать/исправить эту проблему и почему это происходит?

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
 FILE *pwfile;
 char *userName;
 char buf[1024];
 const char s[2] = ":";
 char *token;
 int ch, number_of_lines = 0;
 int i;

 if(argc != 2)
 {
 perror("must supply a user name");

 return -1;
 }

 pwfile = fopen("/home/c2467/passwd", "r");

 if( pwfile == NULL)
 {
 perror( "error opening password file" );

 return -1;
 }

 userName = argv[1];

 do//loop to determine number of lines in the file
 {
 ch = fgetc(pwfile);
 if(ch == '\n')
 number_of_lines++;
 } while (ch != EOF);

 if(ch != '\n' && number_of_lines != 0)
 {
 number_of_lines++;
 }

 for (i = 0; i <= number_of_lines; i++)//iterates through lines of file
 {

 fgets(buf, 1024, pwfile);//stores line into buf

 if (ferror(pwfile) != 0)//tests error indicator for given stream
 {
 perror("fgets error");
 return 1;
 }

 if (feof(pwfile) == 0)//checks if at end of file
 {
 break;
 }

 token = strtok( buf, s);//stores first token of current line in file

 if( strcmp(token, userName) == 0 )//compares token to user name entered
 {
 token = strtok( NULL, s);//Jumps to 2nd token in line, which is irrelevant so do nothing
 token = strtok( NULL, s);//Jumps to 3rd token which is UID number
 printf( "UID: %s\n", token );
 token = strtok( NULL, s);//Jumps to 4th token which is GID number
 printf( "GID: %s\n", token );
 break;
 }

 }
 fclose(pwfile);

 return 0;
}
</string.h></stdio.h></stdlib.h>
1 ответ

Вы читаете файл от начала до конца, чтобы получить количество новых строк.

Однако вы начинаете читать снова, не обращаясь к началу. Это приводит к сбою вашего fgets (чтение после EOF).

вы должны это назвать:

fseek(pwfile, 0 , SEEK_SET);

вы также (feof(pwfile) == 0) от for for (feof(pwfile) == 0), что верно, если файл не находится на конце файла, а это означает, что даже после перемотки вы остановитесь перед обработкой первого линия.

вы должны изменить это на:

if (feof(pwfile))

в противном случае он работает хорошо и правильно. (Тем не менее, я лично ненавижу strtok)

licensed under cc by-sa 3.0 with attribution.