Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 用fgets实现EOF_C_Unix_Eof_Fgets - Fatal编程技术网

C 用fgets实现EOF

C 用fgets实现EOF,c,unix,eof,fgets,C,Unix,Eof,Fgets,我正在编写一个函数来执行一些身份验证操作。我有一个包含所有user\u id:password:flag组合的文件,其结构如下: Users.txt user\u 123:a1b2:0 user\u 124:a2b1:1 user\u 125:a2b2:2 代码如下: int main(){ /*...*/ /*user_id, password retrieving*/ USRPSW* p = malloc(sizeof(USRPSW)); if(p == N

我正在编写一个函数来执行一些身份验证操作。我有一个包含所有
user\u id:password:flag
组合的文件,其结构如下:

Users.txt

user\u 123:a1b2:0 user\u 124:a2b1:1 user\u 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 */

    }   
/*...*/    
}
intmain(){
/*...*/
/*用户id,密码检索*/
USRPSW*p=malloc(sizeof(USRPSW));
if(p==NULL){
fprintf(stderr,“动态分配错误”\n);
退出(退出失败);
}
memset((void*)p,0,sizeof(USRPSW));

如果(usr_psw_read(acc_sock_ds,p->user_id,usr_SIZE)password,psw_SIZE)您可能希望在循环中尝试以下操作:

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标记或文件中有任何错误,循环将终止。我确信这是一种过分的操作,但这些测试对我来说一直都是有效的。

fgets()
在到达文件结尾或错误条件时返回空指针

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

您正在忽略由
fgets()
返回的结果。请不要这样做

请注意,仅检查
feof(fd)
并不能满足您的要求。
feof()
如果到达文件末尾,将返回一个真实的结果。如果遇到错误,
feof()
仍然返回false,如果使用
feof(),您将得到一个无限循环
来决定何时完成。在读取输入失败之前,它不会返回true


大多数C输入函数都会返回一些特殊值来表示没有什么可读的了。对于
fgets()
它是
NULL
,对于
fgetc()
它是
EOF
,等等。如果您愿意,可以调用
feof()
和/或
ferror()
之后,确定没有更多内容可读取的原因。

如果未读取任何字符就到达文件末尾,
fgets
必须返回
NULL
。无论如何,您可以检查
feof(fd)
fgets
之后,没有读取任何内容。恐怕没有设置EOF。我只写了一个包含记录的文件。我还应该显式地设置EOF?怎么做?这不是关于读取时到达文件结尾吗?您没有设置EOF,如果到达文件结尾,下次尝试读取时将在*fd
,因此如果一切正常,那么
feof(fd)
将返回true。如果一切都不正常,嗯。
EOF
是一种条件,而不是水流的一部分。想象水流是来自水龙头的水。当你打开水龙头直到它耗尽时,你会得到更多的水(另一种颜色?)要发出没有水的信号?除非您要使用超过,哦,8kib的数据,否则您最好通过使用
char-usr\u-psw\line[usr\u SIZE+psw\u SIZE+3+1];
而不是动态内存分配来避免
malloc()
的开销和泄漏的可能性,您不会返回已分配的数组,因此这不是这次进行分配的原因-在函数中,这可能是一个很好的原因。(笑着说)我刚才的回答中不是这样说了吗?@Stevevallier或多或少,但我试着更明确地说明基本概念。这是最好的(IMO)对循环条件使用
while(fgets(usr\u psw\u line,sizeof(usr\u psw\u line,fd)!=0)
。在读取之前确实不需要将内存归零。在那里使用
ferror()
feof()
进行测试没有任何好处(因为只有当测试从
fgets()返回时,它们才会计算为true)
返回NULL;因此,它们永远不会导致循环退出)。同意。我试图保留尽可能多的原始代码,以便只有直接回答问题的部分是清楚的。但我完全按照您在我的所有文件读取循环中描述的做。@JonathanLeffler“使用ferror()进行测试”…仅当对fgets()返回的测试返回NULL“-->我认为在极端情况下不会这样。
ferror()
返回可能在调用
fgets()
之前设置的错误标志的状态。
fgets()
没有清除该标志,因此
fgets()
可能返回非
NULL
ferror()
返回true。@chux:我的论点基于这样一个命题,即如果在调用
fgets()
时设置了错误标志,
fgets()
必须失败。然而,我实际上在标准中找不到要求这样做的措辞,尽管我会惊讶地发现一个实现没有这样做。如果跟踪流的状态,除非使用
cleaerr()
。存在一个难以置信的边缘情况。测试
feof()
是毫无意义的。我坚持每天使用我的观察。如果我担心流的错误状态,我会在进入函数时使用
ferror()
。@JonathanLeffler同意日常使用,
feof()
,模糊性和良好的代码将测试
ferror()
,但吸引我注意的是。
fgets()
如果设置了流的错误指示器,则不会自动返回
NULL
,但如果发生读取错误(设置错误指示器会产生副作用),则会返回
NULL