2016-06-29 1 views
0

이 코드는 이진 파일과의 데이터 읽기/쓰기를 수행합니다. 여기서 modify()은 사용자로부터 입력을 받아 파일에서 검색합니다. 발견되면 사용자에게 새 항목을 제공하라는 메시지가 표시되고 이전 항목이 대체됩니다. 나는 다음 항목이 여전히 수정 될 수는 없지만 그와 함께 파일의 내용이 중복 될 경우특정 항목을 수정하는 동안 파일의 모든 내용이 중복됩니다.

이 문제는 fwrite()modify()에서 나는의 while 루프 후 모든 것이 잘 될 것 break하지만 경우 왜 그렇게?

처음에는 파일에 중복 된 항목이 없습니다. 그래서 내가 무엇을 기대합니까 비록 내가 사용하지 않으면 break 루프가 가서 전체 파일을 읽을 때 마침내 종료해야합니다. 여기에서 if(strcmp(e.name,user)==0)은 한 항목에 대해서만 적용되므로 컨트롤은이 if 블록에 한 번만 입력해야합니다. 그렇다면 엔트리는 어떻게 복제 될까요?

#include<stdio.h> 
    #include<stdlib.h> 
    #include<string.h> 

    void add(FILE *); 
    void list(FILE *); 
    void modify(FILE *); 

    struct emp 
    { 
     char name[20]; 
     int id; 
     float sal; 
    }e; 

    void add(FILE *f) 
    { 
     char *p=NULL; 

     printf("\nEnter name id sal\n"); 
     scanf(" %s %d %f", e.name,&e.id,&e.sal); 

     fseek(f,0,SEEK_END); 
     if((fwrite(&e,sizeof(struct emp),1,f))==1) 
     { 
      printf("\nAdded Successfully\n"); 
     } 
     else 
     { 
      printf("\nError wrting to file in ADD func\n"); 
     } 
    } 

    void list(FILE *f) 
    { 
     rewind(f); 
     while(fread(&e,sizeof(struct emp),1,f)>0) 
     { 
      printf("\nRead %s %d %f\n",e.name,e.id,e.sal); 
     } 
    } 

    void modify(FILE *f) 
    { 
     char user[20]; 
     char *p=NULL; 

     printf("\nEnter name to modify\n"); 
     scanf(" %s", user); 

     rewind(f); 

     while(fread(&e,sizeof(struct emp),1,f)==1) 
     { 
      //printf("\n  --------------- %s %d %f\n",e.name,e.id,e.sal); 
      if(strcmp(e.name,user)==0) 
      { 
       //fseek(f,-sizeof(struct emp),SEEK_CUR); 
       printf("\nEnter new name id salary\n"); 
       scanf(" %s %d %f", e.name,&e.id,&e.sal); 

       fseek(f,-sizeof(struct emp),SEEK_CUR); 
       if(fwrite(&e,sizeof(struct emp),1,f)==1) 
       { 
        printf("\nModified successfull!!\n"); 
        //break; 
       } 
       else 
       { 
        printf("\nError while modifying\n"); 
       } 
      } 
      else 
      { 
       printf("\n\nstring not matched\n\n"); 
      } 
     } 

    } 

    int main() 
    { 
     char val='T'; 
     FILE *fp=NULL; 

     if((fp=fopen("database.dat","rb+"))==NULL) 
     { 
      if((fp=fopen("database.dat","wb+"))==NULL) 
      { 
       printf("\nError opening file in wb+ mode\n"); 
       exit(0); 
      } 
     } 

     do 
     { 
      printf("\nEnter a to add, l to list, d to delete, m to modify and e to exit\n"); 
      scanf(" %c", &val); 

      switch(val) 
      { 
       case 'a': 
         add(fp); 
         break; 
       case 'l': 
         list(fp); 
         break; 
       case 'm': 
         modify(fp); 
         break; 
       case 'd': 
    //     del(fp); 
         break; 
       case 'e': 
         fclose(fp); 
         exit(0); 
         break; 
       default: 
         printf("\nInvalid Input\n"); 
         break; 
      } 

     } 
     while(1); 

    } 
+0

당신이 호출되면 정의되지 않은 동작, 아무 것도 발생할 수 있습니다. 'fflush (stdin)'은 정의되지 않은 동작을 호출합니다. 여기서 물어보기 전에 정의되지 않은 동작의 알려진 모든 사례를 제거하십시오. 정의되지 않은 동작이 의미하는 바를 실제로 알지 못하는 것 같으니 그것에 대해 알아보십시오! – Olaf

+0

@Olaf''''fflush (stdin)''''의 모든 현상이 제거되었습니다. 지금 확인하십시오. – ram619

답변

2

가 나는 fread()fwrite() 사이의 문제라고 생각. fwrite()를 사용하여 emp을 수정 한 후에 fseek()을 사용하지 않고 while 루프를 계속 진행합니다. 사실, 이전에 fseek()를 사용하여 되돌아 갔고 괜찮습니다. 지금 당신은 다음과 같이 움직이지 않는) 다른 fseek과을 (배치 할 수 있습니다

이제
fseek(f, 0, SEEK_CUR); 

당신은 휴식을 제거 할 수 있습니다 당신의 Modify() 기능은 것은 다음과 같다 :

void modify(FILE *f) 
{ 
    char user[20]; 
    printf("\nEnter name to modify\n"); 
    scanf("%s",user); 
    fflush(stdin); 
    rewind(f); 

    while(fread(&e,sizeof(struct emp),1,f)==1) 
    { 
     if(strcmp(e.name,user)==0) 
     { 
      printf("\nEnter new name id salary\n"); 
      scanf("%s %d %f",e.name,&e.id,&e.sal); 
      fflush(stdin); 

      fseek(f,-sizeof(struct emp),SEEK_CUR); 
      if(fwrite(&e,sizeof(struct emp),1,f)==1) 
      { 
       printf("\nModified successfull!!\n"); 
       //break; //This can be removed 

       fseek(f, 0, SEEK_CUR); //Place this here 
      } 
      else 
      { 
       printf("\nError while modifying\n"); 
      } 
     } 
     else 
     { 
      printf("\n\nstring not matched\n\n"); 
     } 
    } 
} 
+0

네, 그렇습니다.하지만''''fseek (f, 0, SEEK_CUR);'''를 써야하는 이유는''''fwrite'''''를 쓰면 파일 포인터가 다음을 가리 키기 때문입니다 그것 자체에 항목? 따라서 루프는 다음 항목에서 계속 진행해야합니다. – ram619

+3

[표준 7.21.5.3p7] (http://port70.net/~nsz/c/c11/n1570.html#7.21.5.3p7)을 참조하십시오. "... 출력/입력 바로 뒤에 입력/fflush 함수에 대한 중간 호출없이 ... " – pmg

+0

@pmg"출력은'fflush' 함수 또는 파일 위치 지정 함수'(fseek, fsetpos 또는 rewind)에 대한 중간 호출을하지 않고 직접 입력 다음에 나오면 안됩니다. ''그래서 우리가'fflush()'를 사용한다면 그것은'stdout'을 통해 수행 될 것입니까? – ram619

관련 문제