2014-12-03 6 views
1

마지막 레코드를 두 번 읽는 동안 이진 파일 읽기에 약간의 문제가 있습니다. 4 개의 레코드를 입력했지만 5 개의 레코드가 인쇄되고 마지막 레코드는 항상 두 번 인쇄됩니다.C 바이너리 파일 읽기

int main() 
{ 
    FILE *fp; 
    fp = fopen("file" , "a+"); 

    struct clientsData {int num1; int num2; char str[20]; }; 

    if (getchar()=='w') 
    { 
     int n1,n2; 
     char name[20]; 
     scanf("%d",&n1); 
     scanf("%d",&n2); 
     scanf("%s",name); 

     struct clientsData client; 
     client.num1=n1; 
     client.num2=n2; 
     strncpy(client.str,name, 20); 


     fwrite(&client , 1, sizeof(struct clientsData) , fp); 
    } 
    else 
    { 

     while (!feof(fp)) 
     { 
      struct clientsData client; 
      fread(&client, 1, sizeof(struct clientsData) , fp); 
      printf("%d\t%d\t%s\n",client.num1, client.num2, client.str); 
     } 
    } 
    fclose(fp); 

    return(0); 
} 

출력 :

1 1 asd 
2 3 asd 
23 90 player 
23 23 marin 
23 23 marin 
+0

나는 eof 문자를 찾았을 때 한 번 더 루프를 찾거나 틀렸는가? –

+0

코드가'name'을 읽는 방법에 문제가있다. 'strncpy (client.str, name, 20);'어느 쪽도 결과가'\\ 0 '으로 끝나는 것을 보장하지 않습니다. 'scanf ("% 19s", name); ' – chux

+0

감사합니다 chux! –

답변

2

이 문제는 feof이 작동하는 방식에서 발생합니다. 파일의 한계를 초과하면 true를 리턴합니다 (마지막 문자 다음에 내용을 읽으려고 시도한 경우). 따라서 프로그램이 현재 작동하는 방식은 마지막 유효 데이터를 읽고이를 인쇄하고 데이터를 다시 읽으려고 시도합니다 (fread가 실패하고 데이터 구조의 내용이 동일하며 인쇄하십시오 (동일한 출력을 얻음), feof가 반환합니다. .이 파일의 끝을지나 읽기를 시도, 그래서 루프가 종료 때문에 지금

이 작업을 수행하는 올바른 방법은 사실이 당신 돈으로도 더 효율적입니다

struct clientsData client; 
    while (fread(&client, 1, sizeof(struct clientsData) , fp) == sizeof(struct clientsData)) 
    { 
     printf("%d\t%d\t%s\n",client.num1, client.num2, client.str); 
    } 

하는 것으로 문자를 찾지 마라.

+0

100 thanks man :) –

1

무엇이 일어 났는지를 결정하기 위해 feof()는 true를 돌려 파일의 끝을지나 읽을 시도 후; fread로부터 리턴 값을 검사하여 실제로 데이터를 리턴하는지 확인하십시오.