12

我正在编写一个执行一些身份验证操作的函数。我有一个文件,所有user_id:password:flag夫妻的结构如下:

用户.txt

user_123:a1b2:0 user_124:a2b1:1 user_125:a2b2:2

这是代码:

int main(){
    /*...*/

    /*user_id, password retrieving*/
    USRPSW* p = malloc(sizeof(USRPSW));
    if(p == NULL){
        fprintf(stderr, "Dynamic alloc error\n");
        exit(EXIT_FAILURE);
    }
    memset((void*)p, 0, sizeof(USRPSW));

    if(usr_psw_read(acc_sock_ds, p->user_id, USR_SIZE) <= 0){
        printf("Failed read: connection with %s aborted.\n",
                 inet_ntoa(client_addr.sin_addr));
        close(acc_sock_ds);
        continue;
    }

    if(usr_psw_read(acc_sock_ds, p->password, PSW_SIZE) <= 0){
        printf("Failed read: connection with %s aborted.\n",
                 inet_ntoa(client_addr.sin_addr));
        close(acc_sock_ds);
        continue;
    }

    /*Authentication through user_id, password*/
    FILE *fd;
    fd = fopen(USERSFILE, "r");
    if(fd == NULL){
        fprintf(stderr, "Users file opening error\n");
        exit(EXIT_FAILURE);
    }

    char *usr_psw_line = malloc(USR_SIZE+PSW_SIZE+3+1);
    if(usr_psw_line == NULL){
        fprintf(stderr, "Dynamic alloc error\n");
        exit(EXIT_FAILURE);
    }

    while(1){

        memset((void*)usr_psw_line, 0, sizeof(USR_SIZE+PSW_SIZE+3+1));
        fgets(usr_psw_line, USR_SIZE+PSW_SIZE+3+1, fd);
        printf("%s\n", usr_psw_line);
        fseek(fd, 1, SEEK_CUR);


        /*EOF management*/
        /*usr_id - password matching checking */

    }   
/*...*/    
}

如何管理 EOF 到达?我看到当达到 EOF 时fgets不再编辑 usr_psw_line 但既不返回 NULL 指针。如果达到 EOF,则意味着在用户文件中找不到匹配项并且循环中断。

有人可以给我一些提示或建议吗?

4

2 回答 2

26

fgets()当它到达文件结尾或错误条件时返回一个空指针。

EOF是一个宏,它指定某些其他函数在类似条件下返回的值;它不仅仅是短语“文件结尾”的缩写。)

你忽略了返回的结果fgets()。不要那样做。

请注意,仅检查feof(fd)不会做您想要的。 feof()如果您已到达文件末尾,则返回真结果。如果您遇到错误,feof()仍然返回 false,并且如果您feof()用来决定何时完成,您就会陷入无限循环。并且在您未能读取输入之前它不会返回 true 。

大多数 C 输入函数会返回一些特殊值,以指示没有更多内容可读取。因为fgets()它是NULL,因为fgetc()它是EOF,等等。如果您愿意,您可以致电feof()和/或ferror()事后确定为什么没有更多可阅读的内容。

于 2013-03-18T19:54:31.730 回答
2

您可能想在循环中尝试这样的事情:

while(1)
{
    memset((void*)usr_psw_line, 0, sizeof(USR_SIZE+PSW_SIZE+3+1));
    if( !fgets(usr_psw_line, USR_SIZE+PSW_SIZE+3+1, fd)
     || ferror( fd ) || feof( fd ) )
    {
        break;
    }
    printf("%s\n", usr_psw_line);
    fseek(fd, 1, SEEK_CUR);

    /*EOF management*/
    /*usr_id - password matching checking */

}

fgets使用额外的代码,如果返回 NULL(没有更多数据要读取)或者如果您读取了 EOF 标记或文件上有任何错误,则循环将终止。我敢肯定这是矫枉过正,但这些测试一直对我有用。

于 2013-03-18T19:17:12.710 回答