2013-08-02 18 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主... – 2013-08-02 07:48:06

+0

不要使用'的scanf()'獲取用戶輸入,'與fgets()'是不夠好。並且**檢查** fwrite()的返回值。 – 2013-08-02 07:49:25

+0

void main()的作品。 – JackCColeman

回答

1

感謝你爲這個問題。已修改代碼以便在代碼按ID掃描文件時記住它的文件位置。請參閱curr_pos字段以及ftellfseek如何使用它。此外,還添加了一些fflush語句以使其在Eclipse IDE上運行。

#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

您必須相應STE文件模式「A」是爲了追加,所以每個寫入的數據都將被添加到最後。你必須使用'w +'。編寫函數與它沒有任何關係,除非你必須在之前進行操作。 – Devolus