2013-08-02 4 views
0

C 프로그래밍에서 순차 파일 액세스에 대한 도움이 필요합니다. 다음 코드는 필자가 작성한 코드의 일부입니다.C 프로그래밍을 사용한 순차 파일 액세스

레코드를 삽입하고 레코드를 검색하고 모든 레코드를 표시 할 수 있습니다. 을 수정하고 삭제할 때 필요한 결과를 얻을 수 없습니다. 이 경우 제게 지시 해 주시겠습니까?

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

int c,i,id; 
char name[20]; 
FILE *fp; 
int n; 
int search(FILE *fp,int id); 
void display(FILE *fp); 

typedef struct details 
{ 
    int id; 
    char name[20]; 
}details; 

details d; 


void main() 
{ 
    printf("\nHow many records you would like to insert ? : "); 
    scanf("%d",&n); 
    fp=fopen("one.txt","a"); 
    for(i=0;i<n;i++) 
    { 
     printf("\nEnter id and name"); 
     scanf("%d%s",&d.id,d.name); 
     fwrite(&d,sizeof(d),1,fp); 
    } 
    fclose(fp); 


    while(1) 
    { 
     printf("\nWhat would you like to do now ? : \n"); 
     printf("\n1.Display \t2.Search \t3.Modify \t4.Delete \t5.Exit"); 
     scanf("%d",&c); 
     switch(c) 
     { 
      case 1: 
       fp=fopen("one.txt","r+"); 
       display(fp); 
       fclose(fp); 
       break; 
      case 2: 
       fp=fopen("one.txt","r+"); 
       printf("\nEnter ID to search : "); 
       scanf("%d",&id); 
       if(search(fp,id)) 
       { 
        printf("\nThe record is as follows : "); 
        printf("\n%d\t%s",d.id,d.name); 
       } 
       else 
        printf("\nRecord not found"); 
       fclose(fp); 
       break; 
      case 3: 
       fp=fopen("one.txt","r+"); 
       printf("\nEnter ID to modify d record : "); 
       scanf("%d",&id); 

       if(search(fp,id)) 
       { 
        printf("\nEnter new name"); 
        scanf("%s",d.name); 
        fwrite(&d,sizeof(d),1,fp); 
       } 
       else 
        printf("\nSpecified record not found "); 
       fclose(fp); 
       break;    
     } 
    } 
}       

int search(FILE *fp,int id) 
{ 
    rewind(fp); 
    while(fread(&d,sizeof(d),1,fp)) 
    { 
     if(id==d.id) 
     return 1; 
    } 
    return 0; 
} 

void display(FILE *fp) 
{ 
    rewind(fp); 
    while(fread(&d,sizeof(d),1,fp)) 
    { 
     printf("\n%d\t%s",d.id,d.name); 
    } 
} 
+0

*** int *** main ... –

+0

그리고 사용자 입력을 얻기 위해'scanf()'를 사용하지 않으면'fgets()'만으로 충분합니다. 그리고 ** fwrite()의 리턴 값을 ** 확인한다. –

+0

void main()가 작동합니다. – JackCColeman

답변

1

고맙습니다. 코드가 id로 파일을 스캔 할 때 파일 위치를 기억하도록 코드를 수정했습니다. 필드 curr_pos 및 사용 방법은 ftellfseek입니다. 또한 이클립스 IDE에서 작동 시키려면 몇 가지 fflush 문을 추가해야한다.

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

int c,i,id; 
char name[20]; 
FILE *fp; 
int n; 

long curr_pos; 

int search(FILE *fp,int id); 
void display(FILE *fp); 

typedef struct details 
{ 
    int id; 
    char name[20]; 
}details; 

details d; 


void main() 
{ 
    printf("\nHow many records you would like to insert ? : "); fflush(stdout); 

    scanf("%d",&n); 
    fp=fopen("one.txt","a"); 
    for(i=0;i<n;i++) 
    { 
     printf("\nEnter id and name"); fflush(stdout); 
     scanf("%d%s",&d.id,d.name); 
     fwrite(&d,sizeof(d),1,fp); 
    } 
    fclose(fp); 

    while(1) 
    { 
     printf("\nWhat would you like to do now ? : \n"); 
     printf("\n1.Display \t2.Search \t3.Modify \t4.Delete \t5.Exit\n"); 
     fflush(stdout); 

     scanf("%d",&c); 
     switch(c) 
     { 
      case 1: 
       fp=fopen("one.txt","r+"); 
       display(fp); 
       fclose(fp); 
       break; 
      case 2: 
       fp=fopen("one.txt","r+"); 
       printf("\nEnter ID to search : "); fflush(stdout); 
       scanf("%d",&id); 
       if(search(fp,id)) 
       { 
        printf("\nThe record is as follows : "); 
        printf("\n%d\t%s",d.id,d.name); fflush(stdout); 
       } 
       else 
        printf("\nRecord not found"); 
       fclose(fp); 
       break; 
      case 3: 
       fp=fopen("one.txt","r+"); 
       printf("\nEnter ID to modify d record : "); fflush(stdout); 
       scanf("%d",&id); 

       if(search(fp,id)) 
       { 
        printf("\nEnter new name : "); fflush(stdout); 
        scanf("%s",d.name); 

        // back-up one record, to get to start of current record 
        fseek(fp, curr_pos, 0); 
        fwrite(&d,sizeof(d),1,fp); 
       } 
       else 
        printf("\nSpecified record not found "); 
       fclose(fp); 
       break; 
     } 
    } 
} 

int search(FILE *fp,int id) 
{ 
    rewind(fp); 
    curr_pos = ftell(fp); 
    while(fread(&d,sizeof(d),1,fp)) 
    { 
     if(id==d.id) {return 1;} 

     curr_pos = ftell(fp); 
    } 
    return 0; 
} 

void display(FILE *fp) 
{ 
    rewind(fp); 
    while(fread(&d,sizeof(d),1,fp)) 
    { 
     printf("\n%d\t%s",d.id,d.name); 
    } 
} 

희망이 도움이됩니다.

+0

고마워요 :) 그런데 일식이 fflush()를 기대하는 이유는 무엇입니까? –

2

고정 크기 레코드를 사용하고 있으므로 쉽게 수정할 수 있습니다. 항목을 검색하고 이전 레코드에 새 레코드를 씁니다. 레코드를 검색 한 후에는 레코드 시작 부분까지 뒤로 탐색해야한다는 것을 기억하십시오.

레코드를 삭제하는 경우는 더 어렵습니다. 여기에서 실제로 제거 할 파일을 제외한 모든 레코드를 임시 파일에 쓰고 임시 파일의 이름을 원래 데이터 파일로 바꿔야합니다. 또는 메모리에서 모두 수행 한 다음 파일을 처음부터 메모리의 레코드로 다시 작성하십시오.

0

문제는 파일의 가운데에서 데이터를 제거 할 수 없다는 것입니다. 그래서 당신이 할 수있는 유일한 방법은 처음부터 전체 파일을 다시 쓰기 (직접 또는 복사본 사용)하거나 레코드를 삭제 된 것으로 표시하는 것입니다. 이것은 물론 파일 크기를 남겨 둡니다. 때때로 삭제 된 모든 레코드를 제거하여 파일을 다시 작성할 수 있으므로 파일을 다시 압축 할 수 있습니다.

이것은 실제로 레코드를 삭제하는 빈도에 따라 적합한 방법이며 물론 레코드를 삭제하면 나중에 레코드를 삭제할 때 새 레코드로 덮어 쓸 수 있습니다.

+0

덮어 쓰기를 시도했지만 수정 된 레코드가 파일의 끝에 삽입되어 덮어 쓰지 않습니다. P 필자는 fwrite 매개 변수에서 잘못되었다고 생각합니다 .... –

+0

'a' append를위한 것이기 때문에 모든 데이터 writte가 끝에 추가 될 것입니다. 'w +'를 사용해야합니다. 쓰기 기능은 그 기능과 아무 상관이 없습니다. – Devolus