2013-03-18 34 views
5

Bazı kimlik doğrulama eylemleri gerçekleştiren bir işlev yazıyorum. Böyle yapılandırılmış tüm user_id:password:flag çiftler bir dosya var:EOF'ye Ulaşmak

Users.txt

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

Bu kodudur:

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 */ 

    } 
/*...*/  
} 

nasıl ulaşan EOF yönetebilir? EOF'ye ulaşıldığında, fgets'un artık usr_psw_line düzenlemesi yapmadığını, ancak NULL işaretçisini döndürmediğini gördüm. EOF'a erişilirse, kullanıcı dosyasında hiçbir eşleşmenin bulunmadığı ve döngü kopuk olduğu anlamına gelir.

Birisi bana bazı ipuçları veya öneriler verebilir mi?

+0

Dosya sonuna herhangi bir karakter okumadan ulaşılırsa, 'fgets'' NULL' döndürmekle yükümlüdür. Her neyse, "fgets" bir şey okumadan sonra 'feof (fd) 'yi kontrol edebilirsin. –

+0

EOF'un ayarlanmadığından korkuyorum. İçerdeki kayıtları içeren bir dosya yazarım. Ayrıca açıkça EOF'yi ayarlamalı mıyım? Bunu nasıl yapıyorsun? –

+0

Okurken dosyanın sonuna ulaşmak değil mi? EOF'yi ayarlamazsınız, eğer dosyanın sonuna ulaşılırsa, bir sonraki okuma denemesi bayrağı * fd'de ayarlayacaktır, bu yüzden her şey gerektiği gibi çalışıyorsa feof (fd) 'yi döndürecektir. . Her şey gerektiği gibi çalışmıyorsa, hmmm. –

cevap

1

Sen döngü içinde böyle bir şey denemek isteyebilirsiniz: fgets döner (en fazla veri okumak için) NULL ise

ekstra kod ile
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 */ 

} 

, döngü sona erer veya okuduğunuz eğer EOF işareti veya dosyada herhangi bir hata vardı. Eminim ki bu çok fazla, ama bu testler her zaman benim için çalışmış. Dosya sonuna veya bir hata durumuna ulaştığında boş bir işaretçi döndürür.

+1

Döngü koşulu için 'while (fgets (usr_psw_line, sizeof (usr_psw_line), fd)! = 0)' kullanmak en iyi (IMO) olur. Okunmadan önce belleği sıfırlamaya gerek yok. Ve 'fror()' veya 'feof()' ile test etmenin yararı yoktur (yalnızca fgets() işlevinin dönüşü NULL değerini döndürürse doğru olarak değerlendirdiğinden, bu nedenle döngüde hiçbir zaman neden olmazlar. çıkışa doğru). –

+0

Anlaşmalı. Orijinal kodu olduğu kadar bozulmamış bir şekilde bırakmaya çalıştım, böylece soruyu doğrudan cevaplayan kısımlar açıktı. Ama bütün dosya okuma döngülerinde anlattığın şeyi yapıyorum. –

+0

@JonathanLeffler "ferror() ile sınama ... yalnızca fgets() döndürme sınamasında NULL döndürürse true olarak değerlendirir -> Köşe durumunda düşünmüyorum. 'ferror()', 'fgets()' çağrısından önce ayarlanmış olan hata bayrağının durumunu döndürür. 'fgets()' bu bayrağı temizlemez, yani 'fgets()' '' '' '' '' 'false '' döndüremez ancak' ferror() 'döner. – chux

16

( EOF benzer koşullarda belirli diğer işlevleri tarafından verilen değer belirten bir makro olduğu;. O ifade "dosyasının sonu" için sadece bir kısaltmadır değil)

Sen fgets() dönen sonucu görmezden geliyorsunuz . Bunu yapma.

Sadece feof(fd) numaralı telefonu kontrol etmek istediğinizi yapmayacağınızı unutmayın. Dosyanın sonuna ulaştığınızda feof() doğru bir sonuç döndürür. Bunun yerine bir hatayla karşılaşırsanız, feof() hala yanlış olarak döndürülür ve işiniz bittiğinde karar vermek için feof() kullanıyorsanız, kendinize sonsuz bir döngü elde edersiniz. Ve,'dan sonra, koduna kadar doğru bir şekilde geri dönmez.

Çoğu C giriş işlevi, okunacak başka bir şey olmadığını göstermek için bazı özel değerler döndürür. fgets() için NULL, fgetc() için EOF, vb. İsterseniz feof() ve/veya ferror() numaralarını arayarak numaralı telefonu neden okumayı öğrenebilirsiniz.

+0

(bir gülümseme ile dedi) Daha önceki cevabımda bunu söylemedim mi? –

+1

@SteveValliere Daha fazla veya daha az, ama temel kavramlar hakkında daha açık olmaya çalıştım. –