2

我有一个列出学生的程序,它可以添加新学生,通过学生编号从列表中搜索甚至删除学生,它包含一个学生信息结构。所有信息都在一个名为 REG.DAT 的文件中。我的问题出在 >>DELETE<< 部分。我想按学生编号从列表中删除一个学生,但是当我这样做时,我将列表的其余部分丢失给必须删除的人。请帮我解决这个问题。这是我的代码:

void _remove()
{
    int std_num = 0 , k ;
    int status = 1 , i = -1 , j = 0  ; 
    struct students read[100] ,temp;
    FILE *p ;

    p = fopen("reg.dat","rb");
    if(!p)
    {
        system("cls");
        cout << ">>>>>Register file could not be opened! call the support .<<<<<" << endl;
        _menu();
    }
    while(!feof(p))
    {
        fread(&read[i],sizeof(struct students),1,p) ;
        i++;
    }
    cout << "Enter STD NO. to delete from the list : " << endl ;
    cin >> std_num ;
    for( j = 0 ; j < i ; j++)
    {
        if(std_num == read[j].std_num)
        {
            for( k = j + 1 ; k < i ; k++)
            {
                memcpy(&read[k-1] , &read[k],sizeof (students));
            }
        }
    }
    fclose(p);

    FILE *fp;
    fp = fopen("reg.dat","wb"); 
    for( int l = 0 ; l < i - 2 ; l++)
        fwrite(&read[l], sizeof(struct students), 1 ,fp );
    fclose(fp);
    system("cls") ;
    cout << "STD with NO. " << std_num << " has been removed" << endl ; 
    _menu();
}
4

2 回答 2

3

您不应该使用memcpy重叠的内存部分。您应该改用memmov。正如 memmov 描述所述:

移动内存块 将 num 个字节的值从源指向的位置复制到目标指向的内存块。复制就像使用中间缓冲区一样进行,允许目标和源重叠。

另外: -找到学生编号后,您可以
使用语句停止迭代第一个循环。break

亲切的问候,

于 2012-06-08T06:30:21.120 回答
1

通常的做法是

  • bool is_deleted成员添加到struct student.
  • 删除学生时,将结构更新is_deleted为 true。
  • 阅读学生记录时,忽略已删除的记录。
  • 提供一个程序,逐条读取整个文件记录并将其复制到另一个文件,跳过已删除的记录。然后将此其他文件重命名为原始名称。定期调用此过程,或在程序启动时调用,或仅根据需要手动调用。
于 2012-06-08T06:26:23.010 回答