当我正在处理我的manii项目电话簿时,我在删除功能时遇到一些问题,当有相同名字的多个结果时(我使用名字来搜索我要删除的联系人) 在这种情况下,我在我的结构中创建了额外的变量,称为" ID"和这个ID自动填写我的程序(所以每个用户都有一个唯一的ID),所以我以后可以找到用户想要删除它的结果,它工作正常,但当我从文件中删除一个联系人它离开我有间隙,这对下一次接触有影响 例如:
我有3个联系人,每个人有一个iD 1,2和3,当我删除No.2时,它变为1和3,当我添加一个新用户时,我的自动填充循环将计算联系人的数量(2 )并给新的ID为3,这给我留下3个ID为1,3和3的联系人,这是错误的
所以我想在每次删除操作后重置所有ID,这对我来说似乎很好,这几行应该这样做,我不知道为什么这部分不起作用,甚至我试图把这个循环放在add()函数中,所以它也应该在这个位置很好,但它也不起作用
// reset all ids
rewind(ft);
int id=1;
while(fread(&p,sizeof(p),1,ft)==1)
{
p.id = id;
fwrite(&p,sizeof(p),1,ft);
id++;
}
这是我的完整代码,有0个错误和0个警告,除了重置ID的部分之外它工作正常
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <string.h>
#include <conio.h>
struct address // nested
{
char city[30],
street[30];
int flat;
};
struct phonebook // main
{
int id;
char firstName[20],
lastName[20];
struct address add;
long int phNumber;
char email[50];
};
// functions ...
void launcher();
void menu();
void add();
void load();
void query();
void Delete();
void modify();
void back();
void scan(char *name);
int main()
{
system("color 1e");
printf("Let's start!\n");
launcher();
return 0;
}
void launcher()
{
menu();
}
void back()
{
menu();
}
void menu()
{
system("cls");
printf("\t\t *********** PhoneBook! *************");
printf("\n\n\t\t\t\t <| Menu |>\t\t\n\n");
printf("\t\t1.Add \t2.Load \t3.Query \n\t\t4.Modify \t5.Delete\t6.Exit\n");
switch(getch())
{
case '1' :
add();
break;
case '2' :
load();
break;
case '3' :
query();
break;
case '4' :
modify();
break;
case '5' :
Delete();
break;
case '6' :
printf("the program exit successfully");
exit(0);
break;
default:
system("cls");
int i;
for(i=15 ; i>-1 ; i--)
{
system("cls");
printf("\nInvalid key Entered , please enter any key from 1 to 6 only!\n");
printf("you will back to the main menu automatically in %d seconds",i);
Sleep(1000);
}
menu();
}
}
void add()
{
system("cls");
struct phonebook p; // local define
FILE *f;
f= fopen("data","ab+");
int id=1;
while(fread(&p,sizeof(p),1,f)==1)
{
id++;
}
printf("\nFirst Name : ");
scan(p.firstName);
printf("\nLast Name : ");
scan(p.lastName);
printf("\nEnter the address .. ");
printf("\n\tCity : ");
scan(p.add.city);
printf("\n\tStreet : ");
scan(p.add.street);
printf("\n\tFlat : ");
scanf(" %d",&p.add.flat);
printf("\nPhone number : ");
scanf(" %ld",&p.phNumber);
printf("\nEmail : ");
scan(p.email);
p.id=id; // Auto fill
fwrite(&p,sizeof(p),1,f); // saving the data into a file
fclose(f);
puts("\n\n\t\tdata is saved successfully!");
puts("\t\tEnter any key to back to the main menu");
getch();
back();
}
void load()
{
struct phonebook p;
system("cls");
FILE* f;
f = fopen("data","rb");
if(f==NULL)
{
puts("\n An error occur while opening the file >");
exit(1);
}
while(fread(&p,sizeof(p),1,f)==1)
{
printf("\n\n\t\t\t\t <| loading List |>\t\t\n\n");
printf("First name : %s\nLast name : %s\nAddress Info ...\nCity : %s\nStreet : %s\nFlat : %d\nPhone Number : %ld\nEmail : %s\nid : %d\n",p.firstName,p.lastName,p.add.city,p.add.street,p.add.flat,p.phNumber,p.email,p.id);
puts("\t\t * Enter any key to show more *");
getch();
system("cls");
}
fclose(f);
puts("\t\tno more data to show !");
puts("\t\tEnter any key to back to the main menu");
getch();
back();
}
void query()
{
system("cls");
struct phonebook p;
FILE* f;
f = fopen("data","rb");
if(f==NULL)
{
puts("\n An error occur while opening the file >");
exit(1);
}
char name[50];
int flag=0;
printf("please enter a name : ");
scan(name);
system("cls");
while(fread(&p,sizeof(p),1,f)==1)
{
if(strcmp(name,p.firstName)==0)
{
flag++;
printf("\n[%d] result found\n",flag); // ==> static text
printf("First name : %s\nLast name : %s\nAddress Info ...\nCity : %s\nStreet : %s\nFlat : %d\nPhone Number : %ld\nEmail : %s\n",p.firstName,p.lastName,p.add.city,p.add.street,p.add.flat,p.phNumber,p.email);
puts("");
}
}
if(flag == 0)
{
puts("file not found");
}
fclose(f);
puts("\t\tEnter any key to back to the main menu");
getch();
back();
}
void modify()
{
system("cls");
struct phonebook p,s;
FILE* f;
f = fopen("data","rb+");
if(f==NULL)
{
puts("\n An error occur while opening the file >");
exit(1);
}
char name[50];
int flag=0;
printf("please enter a name : ");
scan(name);
system("cls");
int results[50];
while(fread(&p,sizeof(p),1,f)==1)
{
if(strcmp(name,p.firstName)==0)
{
results[flag] = p.id;
flag++;
printf("\n\n >> full information about the result No. [%d] :- \n",p.id);
printf("First name : %s\nLast name : %s\nAddress Info ...\nCity : %s\nStreet : %s\nFlat : %d\nPhone Number : %ld\nEmail : %s\n",p.firstName,p.lastName,p.add.city,p.add.street,p.add.flat,p.phNumber,p.email);
}
}
if(flag == 0)
{
puts("file not found");
}
else
{
int choice,i,found=0;
int lastResultID = p.id;
puts("Please enter the Number of the result to confirm your order");
scanf(" %d",&choice);
// confirmation
for(i=0 ; i<flag ;i++){
if(results[i] == choice){
found =1;
break;
}
}
if(found == 0){
puts("\n Ops! Result not found.\nmaybe you entered a wrong No. OR an Error occurs Try again.");
Sleep(5000);
back();
}else{
//printf("\n%d\n",lastResultID);
puts("\n >> Are you want to modify this result ? type (Y) for Yes or (N) for No !");
char c = getch();
if( c == 'Y' || c == 'y')
{
system("cls");
printf("\nFirst Name : ");
scan(s.firstName);
printf("\nLast Name : ");
scan(s.lastName);
printf("\nEnter the address .. ");
printf("\n\tCity : ");
scan(s.add.city);
printf("\n\tStreet : ");
scan(s.add.street);
printf("\n\tFlat : ");
scanf(" %d",&s.add.flat);
printf("\nPhone number : ");
scanf(" %ld",&s.phNumber);
printf("\nEmail : ");
scan(s.email);
fseek(f,-sizeof(p)*(lastResultID-choice+1),SEEK_CUR);
s.id=choice;
fwrite(&s,sizeof(p),1,f); // saving
puts("\n\t\tyour data is modified!");
fclose(f);
puts("\t\tEnter any key to back to the main menu");
getch();
back();
}
else
{
system("cls");
puts("nothing change ! , press any key to back to the main menu !");
getch();
back();
}
}
}
}
void Delete()
{
int found =0;
system("cls");
struct phonebook p,s;
FILE* f;
FILE* ft;
f = fopen("data","rb");
ft = fopen("temp","ab+");
if(f == NULL || ft == NULL)
{
puts("\n An error occur while opening the file >");
perror("fopen() failed");
exit(1);
}
char name[50];
int flag=0,i;
int results[50];
printf("please enter a name : ");
scan(name);
system("cls");
while(fread(&p,sizeof(p),1,f)==1)
{
if(strcmp(name,p.firstName)==0)
{
results[flag] = p.id;
flag++;
printf("\n\n >> full information about the result No. [%d] :- \n",p.id);
printf("First name : %s\nLast name : %s\nAddress Info ...\nCity : %s\nStreet : %s\nFlat : %d\nPhone Number : %ld\nEmail : %s\n",p.firstName,p.lastName,p.add.city,p.add.street,p.add.flat,p.phNumber,p.email);
}
}
if(flag == 0)
{
puts("file not found");
}
else{
puts(" ");
int choice,check=0;
puts("please enter the number of the result which you want to delete");
scanf(" %d",&choice);
// confirmation
for(i=0 ; i<flag ;i++){
if(results[i] == choice){
check =1;
break;
}
}
if(check == 0){
puts("\n Oops! Result not found.\nmaybe you entered a wrong No. OR an Error occurred Try again later.");
Sleep(3500);
back();
}else{
puts("\n >> Do you want to delete this result ? type (Y) for Yes or (N) for No !");
char c = getch();
rewind(f); // reset the pointer
if( c == 'Y' || c == 'y')
{
system("cls");
while(fread(&p,sizeof(p),1,f)==1)
{
if(choice != p.id)
fwrite(&p,sizeof(p),1,ft);
if(choice == p.id)
found++;
}
//perror("fread() failed");
if(found == 0)
{
puts("An error occurred , please try again");
remove("temp");
Sleep(3500);
back();
fclose(f); // ==?
fclose(ft); // ==?
}
else
{
// reset all ids
rewind(ft);
int id=1;
while(fread(&p,sizeof(p),1,ft)==1)
{
p.id = id;
fwrite(&p,sizeof(p),1,ft);
id++;
}
fclose(f); // ==?
fclose(ft); // ==?
remove("data");
int c = rename("temp","data");
puts("file is deleted successfully");
if(c != 0)
perror("rename() failed"); // handling for rename error
}
puts("\t\tEnter any key to back to the main menu");
getch();
back();
}
else
{
system("cls");
puts("nothing changed ! , press any key to back to the main menu !");
getch();
back();
}
}
}
/*else
{
puts("\n >> Are you want to delete this result ? type (Y) for Yes or (N) for No !");
char c = getch();
if( c == 'Y' || c == 'y')
{
rewind(f);
while(fread(&p,sizeof(p),1,f)==1)
{
if(strcmp(name,p.firstName)!=0)
fwrite(&p,sizeof(p),1,ft);
}
fclose(f);
fclose(ft);
remove("data");
int c = rename("temp","data");
puts("file is deleted successfully");
if(c != 0)
perror("rename() failed");
// reset all ids
int id=1;
while(fread(&p,sizeof(p),1,f)==1)
{
p.id = id;
fwrite(&p,sizeof(p),1,f);
id++;
}
puts("\t\tEnter any key to back to the main menu");
getch();
back();
}
else
{
system("cls");
puts("nothing change ! , press any key to back to the main menu !");
getch();
back();
}
}*/
}
void scan(char *name)
{
int i=0,j;
char c,ch;
do
{
c=getch();
if(c!=8&&c!=13)
{
*(name+i)=c;
putch(c);
i++;
}
if(c==8)
{
if(i>0)
{
i--;
}
// printf("h");
system("cls");
for(j=0; j<i; j++)
{
ch=*(name+j);
putch(ch);
}
}
}
while(c!=13);
*(name+i)='\0';
}
提前致谢
答案 0 :(得分:1)
如果使用最高的id + 1而不是计算它们呢?
int id = 1;
while(fread(&p,sizeof(p),1,f)==1)
{
if (p.id >= id) id = p.id+1;
}
答案 1 :(得分:0)
如果没有干预fread
,您无法交错fwrite
和fseek
:
7.21.5.3/7 当使用更新模式打开文件时(&#39; +&#39;作为上述模式参数值列表中的第二个或第三个字符),可以在关联的流上执行输入和输出。但是,如果没有对
fflush
函数或文件定位函数(fseek
,fsetpos
或rewind
)的干预调用,输出不应直接输入,并且除非输入操作遇到文件结束,否则输入不应直接跟随输出,除非输入操作遇到文件结束。