首页 文章

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

提问于
浏览
0

我正在尝试制作一个简单的C程序,它逐行检查Linux密码文件,搜索以命令行参数提供的用户名开头的行 . 每行包含由冒号分隔的几个标记 . 第一个令牌是用户名,第二个是无关紧要,第三个是需要打印的用户ID(UID)号,第四个令牌是需要打印的组ID号(GID) .

使用一些打印测试并在线搜索解决方案,我认为我的令牌变量在将其分配给我的第一个strtok调用后仍为NULL(此时令牌的printf不打印任何内容) . 然后,使用strcmp将NULL令牌与产生分段错误错误的用户名进行比较 . 如果到目前为止我的分析是正确的(这可能不是因为我是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;
}

1 回答

  • 1

    您从头到尾读取文件以获取新行的计数 .

    但是,你再次开始阅读而不回头 . 这会导致您的fgets失败(在EOF之后读取) .

    你必须这样称呼:

    fseek(pwfile, 0 , SEEK_SET);
    

    你也打破 (feof(pwfile) == 0) 上的for,如果文件不在文件的末尾,这是正确的,这意味着,即使在倒带之后,你也会在处理第一行之前停止 .

    你应该改为:

    if (feof(pwfile))
    

    否则它似乎工作得很好而且正确 . (但是,我个人讨厌strtok)

相关问题