简体   繁体   English

使用strtok()和strcmp()的分段错误错误

[英]Segmentation fault error using strtok() and strcmp()

I am trying to make simple C program which checks a Linux password file line-by-line searching for the line beginning with a username supplied by a command line argument. 我正在尝试制作简单的C程序,该程序逐行检查Linux密码文件,以命令行参数提供的用户名开头的行。 Each line consists of several tokens delimited by a colon. 每行包含几个以冒号分隔的标记。 The first token is the username, the 2nd is irrelevant, the 3rd is a user id (UID) number which needs to be printed, and the 4th token is the group id number (GID) which also needs to be printed. 第一个令牌是用户名,第二个令牌是无关的,第三个令牌是需要打印的用户ID(UID)号,第四个令牌是也需要打印的组ID号(GID)。

Using a few print tests and searching online for solutions, I think my token variable remains NULL after assigning it to my first strtok call (printf of the token at this point prints nothing). 使用一些打印测试并在线搜索解决方案,我认为将令牌变量分配给我的第一个strtok调用后,令牌变量仍然为NULL(此时令牌的printf不会打印任何内容)。 Then, the NULL token is compared, using strcmp, to the username which produces the segmentation fault error. 然后,使用strcmp将NULL令牌与产生分段错误错误的用户名进行比较。 If my analysis thus far is correct (which it may very well not be since I am new to C), how can I avoid/fix this problem and why is this happening? 如果到目前为止我的分析是正确的(由于我是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;
}

You read the file from the beginning to the end to get the count of new lines. 您从头到尾读取文件以获取新行数。

However, you start reading again without seeking back to the beginning. 但是,您可以重新开始阅读而无需回到开头。 This causes your fgets to fail (read after EOF). 这会导致您的fget失败(在EOF之后读取)。

you have to call this: 您必须致电:

fseek(pwfile, 0 , SEEK_SET);

you also break from the for on (feof(pwfile) == 0) , which is true in case that the file is not at teh end of file, which means, even after the rewind, you'll stop before processing of the first line. 您还会从for中断(feof(pwfile) == 0) ,这在文件不在文件末尾的情况下是正确的,这意味着,即使倒带后,您也将在处理第一个文件之前停止线。

you should change that to: 您应该将其更改为:

if (feof(pwfile))

otherwise it seem to work nice and correctly. 否则,它似乎可以正常工作。 (However, I personally hate strtok) (但是,我个人讨厌strtok)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM