C 在读取密码文件时,程序从未遇到EOF

C 在读取密码文件时,程序从未遇到EOF,c,linux,unix,C,Linux,Unix,我目前正在编写的部分程序需要检查用户是否存在(这是针对unix系统的)。但是,在为用户读取密码文件时,永远不会达到EOF,因此会创建一个无休止的循环。我可能做错了什么 int readPass; int userExists = 0; // 0 means user doesn't exist, 1 means they do // open password file to read in usernames int pass

我目前正在编写的部分程序需要检查用户是否存在(这是针对unix系统的)。但是,在为用户读取密码文件时,永远不会达到EOF,因此会创建一个无休止的循环。我可能做错了什么

        int readPass;

        int userExists = 0; // 0 means user doesn't exist, 1 means they do

        // open password file to read in usernames
        int passFD = open("/etc/passwd", O_RDONLY);

        // open password file to read character by character
        FILE* pass = fopen("/etc/passwd", "r");

        // c-string to store usernames
        char passUser[100];

        // read through the password file
        while (readPass != EOF)
        {
            int numPass = 0;

            // read until reaching a colon, this is the username of the current line
            while (readPass != ':')
            {
                readPass = fgetc(pass);
                numPass += 1;
            }
            // store username is a c-string
            read(passFD, passUser, numPass);
            passUser[numPass - 1] = '\0';

            // if the user exists, stop checking
            if ((strcmp(passUser, argv[user])) == 0)
            {
                userExists = 1;
                break;
            }

            // read junk until next line
            readPass = NULL;
            int junksRead = 0;
            char passJunk[100];
            while (junksRead < 6)
            {
                numPass = 0;
                readPass = NULL;
                while (readPass != ':' && readPass != '\n' && readPass != EOF)
                {
                    readPass = fgetc(pass);
                    numPass += 1;
                    //printf("%c\n", readPass);
                }
                read(passFD, passJunk, numPass);
                junksRead += 1;
            }
        }

        // if the user doesn't exist, end the program
        if (userExists == 0)
        {
            printf("%s does not exist\n", argv[user]);
            return 0;
        }`
int-readPass;
int userExists=0;//0表示用户不存在,1表示用户不存在
//打开密码文件以读取用户名
int passFD=open(“/etc/passwd”,仅限ordu);
//打开密码文件以逐个字符读取
文件*pass=fopen(“/etc/passwd”,“r”);
//用于存储用户名的c字符串
charpassuser[100];
//通读密码文件
while(readPass!=EOF)
{
int numPass=0;
//读取直到到达冒号,这是当前行的用户名
while(readPass!=':')
{
readPass=fgetc(通过);
numPass+=1;
}
//存储用户名是一个c字符串
读取(passFD、passUser、numPass);
密码用户[numPass-1]='\0';
//如果用户存在,请停止检查
if((strcmp(passUser,argv[user]))==0)
{
userExists=1;
打破
}
//阅读垃圾直到下一行
readPass=NULL;
int junksRead=0;
字符密码垃圾[100];
而(junksRead<6)
{
numPass=0;
readPass=NULL;
while(readPass!=':'&&readPass!='\n'&&readPass!=EOF)
{
readPass=fgetc(通过);
numPass+=1;
//printf(“%c\n”,readPass);
}
读取(passFD、passJunk、numPass);
junksRead+=1;
}
}
//如果用户不存在,请结束程序
如果(userExists==0)
{
printf(“%s不存在\n”,argv[user]);
返回0;
}`

您可能会陷入另一个while循环中。确保每个while循环都在检查EOF,尤其是:

while (readPass != ':' && readPass != EOF)
            {
                readPass = fgetc(pass);
                numPass += 1;
            }

你可能会在另一个循环中卡住。确保每个while循环都在检查EOF,尤其是:

while (readPass != ':' && readPass != EOF)
            {
                readPass = fgetc(pass);
                numPass += 1;
            }

如果您没有其他选择,则可以通过自己阅读
/etc/passwd
文件来搜索用户。但是,更好的方法是使用一个现有的函数来完成这项工作:从标题开始。不需要重新发明那些已经做过并且有效的东西

可能的代码如下所示:

#include <stdio.h>
#include <pwd.h>
#include <errno.h>

int main()
{
  //reset errno to be able to detect errors
  errno = 0;
  struct passwd * result = getpwnam("username");
  //Return value NULL could either mean error or "user not found".
  if (result == NULL)
  {
    //If errno is not zero, then an error occurred while getpwnam() was called.
    if (errno != 0)
      printf("An error occurred while searching for the user.\n");
    //Otherwise the user just does not exist.
    else
      printf("User does not exist!\n");
  }
  //Not NULL: user was found.
  else
  {
    printf("User exists.\n");
  }

  return 0;
}
#包括
#包括
#包括
int main()
{
//重置errno以检测错误
errno=0;
结构passwd*result=getpwnam(“用户名”);
//返回值NULL可能表示错误或“未找到用户”。
如果(结果==NULL)
{
//如果errno不为零,则调用getpwnam()时出错。
如果(错误号!=0)
printf(“搜索用户时出错。\n”);
//否则用户就不存在了。
其他的
printf(“用户不存在!\n”);
}
//不为NULL:未找到用户。
其他的
{
printf(“用户存在。\n”);
}
返回0;
}

如果您没有其他选择,您可以自己阅读
/etc/passwd
文件来搜索用户。但是,更好的方法是使用一个现有的函数来完成这项工作:从标题开始。不需要重新发明那些已经做过并且有效的东西

可能的代码如下所示:

#include <stdio.h>
#include <pwd.h>
#include <errno.h>

int main()
{
  //reset errno to be able to detect errors
  errno = 0;
  struct passwd * result = getpwnam("username");
  //Return value NULL could either mean error or "user not found".
  if (result == NULL)
  {
    //If errno is not zero, then an error occurred while getpwnam() was called.
    if (errno != 0)
      printf("An error occurred while searching for the user.\n");
    //Otherwise the user just does not exist.
    else
      printf("User does not exist!\n");
  }
  //Not NULL: user was found.
  else
  {
    printf("User exists.\n");
  }

  return 0;
}
#包括
#包括
#包括
int main()
{
//重置errno以检测错误
errno=0;
结构passwd*result=getpwnam(“用户名”);
//返回值NULL可能表示错误或“未找到用户”。
如果(结果==NULL)
{
//如果errno不为零,则调用getpwnam()时出错。
如果(错误号!=0)
printf(“搜索用户时出错。\n”);
//否则用户就不存在了。
其他的
printf(“用户不存在!\n”);
}
//不为NULL:未找到用户。
其他的
{
printf(“用户存在。\n”);
}
返回0;
}

为什么要将
NULL
赋值给
int
?还有一些内部文件读取循环,它们甚至不检查
EOF
。代码完全是一团糟。这应该做什么:
read(passFD,passUser,numPass)?顺便说一句:fgets()是你的朋友。NULL存在是因为我以前将它作为字符,但忘了更改它。此外,并非所有循环都需要检查EOF,只有一个循环将一直读取到行尾。例如,读取用户名永远不会到达EOF,因此检查是没有意义的。将文件中当前行的用户名存储到passUser数组“读取用户名永远不会到达EOF,因此检查“ha,ha,ha,ha,ha,haw”是没有意义的。您为什么要将
NULL
分配给
int
?还有一些内部文件读取循环,它们甚至不检查
EOF
。代码完全是一团糟。这应该做什么:
read(passFD,passUser,numPass)?顺便说一句:fgets()是你的朋友。NULL存在是因为我以前将它作为字符,但忘了更改它。此外,并非所有循环都需要检查EOF,只有一个循环将一直读取到行尾。例如,读取用户名永远不会到达EOF,因此检查是毫无意义的。将文件中当前行的用户名存储到passUser数组“读取用户名永远不会到达EOF,因此检查”ha,ha,ha,ha,haThanks!是毫无意义的!成功了。我只是想,因为用户名是文件中的第一件事,所以我不必在那里检查EOF。我还认为,如果EOF是在一个pre中发现的,那么外部循环将捕获它