我目前正在学习C,我的作业是创建一个在记录中的结构,我应该使用链接列表。我的功能之一是输入姓氏来删除记录。我使用fgets后停止工作(没有崩溃仅停止(。
struct students
{
char firstname[21];
char lastname[21];
double score;
int zip;
struct students* next;
};
struct students* head;
void add()
{
struct students* new_node=(struct students*)malloc(sizeof(struct students));
struct students *past=head;
fflush(stdin);
new_node->next=NULL;
printf("Enter data: n");
printf("First name: ");
fgets(new_node->firstname, 21, stdin);
printf("Last name: ");
fgets(new_node->lastname, 21, stdin);
printf("Score: ");
scanf("%lf", &new_node->score);
printf("ZIP code: ");
scanf("%d", &new_node->zip);
if(head==NULL)
{
head=new_node;
return;
}
while(past->next!=NULL)
{
past=past->next;
}
past->next=new_node;
return;
}
void delrec()
{
char last[21];
printf("Enter last name: ");
fflush(stdin);
fgets(last, 21, stdin);
struct students* temp=head;
last[strcspn(last, "n")]=0;
if(strcmp(temp->lastname, last)==0)
{
struct students *next=temp->next;
free(temp);
temp=next;
}
while(temp!=NULL)
{
if(temp->next==NULL)
{
return;
}
if(strcmp(temp->next->lastname, last)==0)
{
struct students *next=temp->next->next;
free(temp->next);
temp->next=next;
}
temp=temp->next;
}
}
int main()
{
head=NULL;
int i, x, y;
printf("Enter 5 records:n");
for(i=0; i<5; i++)
{
add();
}
print();
printf("What would you like to do?n");
y=1;
while(y)
{
printf("Print records (press 1)n");
printf("Add new record (press 2)n");
printf("Delete record (press 3)n");
printf("Exit the program (press 0)n");
scanf("%d", &x);
switch(x)
{
case 0:
y=0;
break;
case 1:
print();
break;
case 2:
add();
break;
case 3:
delrec();
break;
}
}
return 0;
}
我认为这与链接列表无关,但也许是我的输入或其他内容。
edit1:我发现错误是我忘了在DelRec的while循环中提供temp=temp->next;
。我当前的问题现在是,即使我键入确切的姓氏,它也不会从列表中删除记录/UNLINK。我已经编辑了代码以显示我的进度。
edit2:没有大的编辑理由,但是我没有得到不必要的答案,我能够弄清楚如何从链接列表中删除结构。但是,如果我从头部删除结构,它将打印出非常奇怪的文本,再次编辑代码以显示进度。
fgets()
也将在尾随n
中读取。所以用
fgets(last, 21, stdin);
如果您将"Doe"
作为输入,则存储的是"Doen"
。
您将此字符串与n
的末尾与您的记录进行了比较。
您需要删除尾随的n
。它可以用
last[strlen(last)-1] = ' ';
编辑:正如Joop指出的那样,如果字符串为空,则strlen()
可以返回0
。如果strlen(last)
给出0
,则last[strlen(last)-1]
。如前所述,您可以使用strcspn()
而不是
last[strcspn(last, "n")] = ' ';
strcspn(char *dest, char *src)
返回字符串的最大初始段的长度,其第一个参数指向的第一个参数仅由字符串指向第二个参数指向的字符字符组成。
P>
还要注意,fflush(stdin)
的效果不确定。标准说(按照此答案(,
如果流指向最新操作未输入的输出流或更新流,则FFLUSH函数会导致该流传递到主机环境的任何未成文数据,以写入文件;否则,行为是不确定的。
请查看这个问题。
在您的代码行
中printf("Enter data: n");
in add((正在创建问题,因为printf((在输入缓冲区中留下了fgets((将读取它的空间。
printf((之后,将一个解决方案放在fflush(stdin(之后:
printf("Enter data: n");
fflush(stdin);
或者您可以使用scanf((来吸用具有空间的字符,例如:
scanf("%[^n]",new_node->firstname);