0

我需要你的帮助来进行 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); 
    }
}
4

3 回答 3

2

由于您使用的是固定大小的记录,因此很容易修改。只需搜索条目并将新记录写在旧记录上。请记住,在搜索记录后,您必须向后查找记录的开头。

至于删除记录,那就更难了。在这里,您实际上必须将除要删除的记录之外的所有记录写入临时文件,然后将临时文件重命名为原始数据文件。或者全部在内存中完成,然后用内存中的记录从头开始重写文件。

于 2013-08-02T07:39:23.277 回答
1

谢谢你的这个问题。已修改您的代码以记住其文件位置,因为代码按 id 扫描文件。请参阅该字段curr_pos以及它是如何被ftell和使用的fseek。此外,添加了一些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);
    }
}

希望这可以帮助。

于 2013-08-03T21:41:29.293 回答
0

问题是您无法从文件中间删除数据。因此,您唯一能做的就是从头开始重写整个文件(直接或使用副本),或者您可以将记录标记为已删除。当然,这将使文件大小保持不变。您可以不时重写文件以删除所有已删除的记录,从而再次压缩文件。

这是否可行取决于您真正删除记录的频率,当然,如果记录被删除,您可以在稍后插入一条记录时用新记录覆盖它。

于 2013-08-02T07:49:36.720 回答