3

プログラムは、従業員 ID に従って特定のレコードを変更または削除する必要があります。変更部分では、変更されたレコードをファイルの最後に新しいレコードとして書き込みます。削除部分は一度だけ機能し、セグメンテーション違反が発生します。

変更:

編集したレコードを同じ位置に書き換えるようにコードを変更するにはどうすればよいですか?

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

struct record_em{
    int id;
    char name[20];
    int salary;
    int age;
};

int main( void )
{
    struct record_em employee;
    FILE *fp;
    int n;
    int ch;
    fp = fopen("empRecord.dat","rb+");

    printf("Enter Id Number:\n");
    scanf("%d",&n);
    rewind(fp);
    while (!feof(fp)){

        fscanf(fp,"%d %s %d %d", &employee.id, employee.name, &employee.salary, &employee.age);

        if (employee.id==n){
            printf("%d %s %d %d \n",employee.id, employee.name, employee.salary,employee.age);
            printf("\n Do you want to change the name ?\n");
            scanf("%d",&ch);

            if (ch==1){
                printf("Enter new name:\n");
                scanf("%s",employee.name);
            }
            printf("\n Do you want to change the salary ?(y/n)\n");
            scanf("%d",&ch);

            if ( ch==2 ){
                printf("Enter new salary:\n");
                scanf("%d",&employee.salary);
            }
            printf("\n Do you want to change the age ?(y/n)\n");
            scanf("%d",&ch);

            if ( ch==3 ){
                printf("Enter new age:\n");
                scanf("%d",&employee.age);
            }
            fseek(fp,-sizeof(employee),SEEK_CUR);
            fprintf(fp, "%d %s %d %d\n", employee.id, employee.name, employee.salary, employee.age);
            exit(0);
        }
    }
    printf("Record Not Found \n");
    return 0;
}

削除:

何度でもレコードを削除できるようにコードを変更するにはどうすればよいですか?

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

struct record_em{
    int id;
    char name[20];
    int salary;
    int age;
};

int main()
{
    struct record_em employee;
    FILE *fp, *ft;
    int n;
    fp = fopen("empRecord.dat","r");
    ft = fopen("Temp.dat","wb+");

    printf("\nEnter ID of employee to delete ");

    scanf("%d",&n);
    rewind(fp);
    while (!feof(fp)){
        fscanf(fp,"%d %s %d %d", &employee.id, employee.name, &employee.salary,  &employee.age);

        if(employee.id!=n){
            fprintf(ft, "%d %s %d %d\n", employee.id, employee.name, employee.salary, employee.age);
        }
    }

    fclose(fp);
    fclose(ft);
    remove("empRecord.dat");
    rename("Temp.dat","EempRecord.dat");

    return 0;
}
4

4 に答える 4

3

コードのキーポイントは次のとおりです。

void update(char filename[],char name[])
{
    int records=0;
    FILE *fp = fopen(filename,"rb+");
    while(fread(&st,sizeof(st),1,fp)==1)
    {
         if(strcmp(name,st.name)==0)
         {
              printf("\nEnter new name: ");
              scanf("%s",st.name);
              printf("\nEnter new roll no.: ");
              scanf("%d",&st.roll);
              fseek(fp,sizeof(struct student)*records,SEEK_SET);//This is key line..
              fwrite(&st,sizeof(st),1,fp);
         }
         records++; // in the while loop...
    }
    fclose(fp);
}

以下は、学生の構造です。

struct student{
     int roll;
     char name[20];
}st;

これは、レコードを変更/更新する一般的な方法です。従業員構造にも同じ構文を使用できます。

于 2013-11-30T19:01:45.160 に答える
1

これがあなたの問題だと思います。最初はマイナス記号が付いているので、sizeofそれを見るのは少し奇妙です。次にSEEK_CUR、現在のファイルよりも遠くに移動するので、ここを見てくださいfseek()、rewind()

fseek(fp,-sizeof(employee),SEEK_CUR); //This is not the definitive read below.
         ^------minus symbol.  ^------- the type of seek.

いくつかの変更を行うことをお勧めします。

  1. Formatted Fileあなたの人生を楽にするためにコモンを使用してください、「完璧はシンプルさです」を覚えておいてください。

  2. SEEK_SETファイルの先頭からの相対位置を使用するために使用し、2番目にstruct's sizeのパラメータとしてを使用しますsizeof

    fseek( fp, sizeof( struct record_em), SEEK_SET );
    
  3. シンクのキーとしてIDを使用memberし、連続した一連の数字を使用しますが、明らかに、100、1000人の雇用者でファイルを作成する必要があります。

    1 Andrew 20000 27
    ^   ^      ^    ^_____ age 
    |   |      |__________ salary ( I would have used double here)
    |   |_________________ name
    |_____________________ id ( Key for the relative position from the beginning)
    
  4. 考えを変える必要があります。レコードを「削除」することを想像すると、空白(キーを除く)を記述します。例貧しいアンドリューが解雇され、彼のレコードを削除するとします。

    1 "Empty space"   0   0
    ^       ^         ^   ^______ age (0 = nothing)
    |       |         |__________ salary (0 = nothing)
    |       |____________________ name ("" = nothing)
    |____________________________ id ( Key for the relative position from the beginning)
    

PD:現在、より多くの情報を追加しています。

于 2012-11-24T11:04:37.090 に答える
1

テキスト ファイル fprintf を操作するために使用することを意図した C 関数を使用してバイナリ ファイルを操作するのは良くありません。

たとえば、あなたのコードでは次のように表示されます。

fseek(fp,-sizeof(employee),SEEK_CUR);
fprintf(fp, "%d %s %d %d\n", employee.id, employee.name, employee.salary, employee.age);

ファイル内をバイナリファイルとして移動してから文字を書き込むため、これは問題を引き起こします。代わりに fwrite 関数を使用する必要があります。

私の推奨事項: プログラム全体を確認し、永続化戦略を定義して、これと一貫性を保つようにしてください。

于 2012-11-24T10:21:11.140 に答える