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 に達した場合、users ファイルに一致するものが見つからず、ループが中断されたことを意味します。

誰かが私にいくつかのヒントや提案を与えることができますか?

4

2 に答える 2

26

fgets()ファイルの終わりまたはエラー状態に達したときにヌル ポインターを返します。

(EOF同様の条件で特定の他の関数によって返される値を指定するマクロです。これは単に「ファイルの終わり」という句の省略形ではありません。)

によって返された結果を無視していますfgets()。そうしないでください。

チェックfeof(fd)するだけでは、希望どおりにならないことに注意してください。 feof()ファイルの最後に到達した場合、真の結果を返します。代わりにエラーが発生した場合でも、false が返されます。いつ終了するかを決定するために をfeof()使用している場合は、無限ループが発生します。feof()そして、入力の読み取りに失敗するまで trueを返しません。

ほとんどの C 入力関数は、読み取るものがこれ以上ないことを示す特別な値を返します。それfgets()NULLfgetc()それEOFは などです。feof()必要に応じて、 and/or after を呼び出して、読むものが何もない理由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 */

}

追加のコードを使用すると、NULL (読み取るデータがない) が返された場合、または EOF マークが読み取られた場合、またはファイルにエラーが発生した場合に、ループが終了fgetsします。やり過ぎだとは思いますが、これらのテストは常にうまくいきました。

于 2013-03-18T19:17:12.710 に答える