【问题标题】:Linked List in C : Having issues with entering string and displaying itC 中的链表:输入字符串并显示时出现问题
【发布时间】:2012-12-12 18:50:36
【问题描述】:

我已经为链表编写了代码:

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

struct student{
       char name[256];
       int id;  
       struct student *next;
};
  struct student *start;
  struct student *last;     

void enter(void);
void add( struct student *i,struct student **last);
void display(struct student *first);       

int main(int argc, char *argv[])
{
  start=last=NULL;

   enter();
   enter();
   enter();
   display(start);

  system("PAUSE");  
  return 0;
}

void add( struct student *i,struct student **last)
{
     if (!*last){ *last=i; start=i;}
     else {(*last)->next=i;*last=i;}
     i->next=NULL;

     }
void enter(void)
{
   struct student *info;

   info=(struct student *)malloc(sizeof(struct student));



    printf("Enter the name of the student:\n");
    fgets(info->name,255,stdin);
    fflush(stdin);
    // gets(info->name);
     printf("Enter the student id:\n");
     scanf("%d%",&info->id); 
     add(info,&last);

 }

 void display(struct student *first)
 {
      while(first)
      {
                  printf("\n\n\n\nName: %s\n",first->name);
                  printf("Id: %d\n", first->id);
                  first=first->next;
                  }
  }

它确实创建了一个链接列表,但是当我尝试输入值时:它显示

对于第一个元素,它为 id 正确使用名称,我需要在 id 数字之后手动输入 \n(否则它不会退出 scanf 模式),并且从第二个元素开始,它不会提示输入名称并且它跳过“输入名称”并询问 id 我需要在哪里再次手动输入 \n。在显示链表元素时,它确实显示名字,但从第二个名字开始显示\n。我已经使用过 fflush(stdin)。您能否让我知道为什么会出现这种行为?我附上了o/p图片。

谢谢

【问题讨论】:

    标签: c visual-studio


    【解决方案1】:

    如果我有五分钱...

    不管怎样,这里有很多问题:

    1) 不要fflush(stdin),这是未定义的行为

    2) 将scanfs 和fgetss 混用绝不是一个好主意,它只会让事情变得混乱。

    scanf(" %s", info->name); // will do instead of your fgets statement
    

    3) 你的 scanf 中有一个额外的%

    scanf("%d%",&info->id);  // should be scanf("%d",&info->id);
    

    为了完整性...

    为什么你现在遇到问题:

    fgets() 接受一个字符串并包含换行符,因此当您询问名称时,您会得到“name\n”

    scanf() 获取数字并离开换行符。因此,当您询问 ID 时,您会输入数字,但换行符 '\n' 仍位于 stdin 中。

    下次您的fgets() 运行时,它会自动将其作为第二个名称的输入。似乎“跳过”输入请求。


    编辑
    如果您使用fgets() 的原因是读取其中包含空格的字符串(如"first_name last_name"),则可以使用scanf() 以及使用否定扫描集选项来完成:

    scanf(" %[^\n]",info->name); 
    

    【讨论】:

    • 谢谢 Mike,“3) 你的 scanf: 中有一个额外的 % - 它解决了 \n 问题,但字符串之一仍然存在。 scanf("%s",info->name);在名字和姓氏之间不占用空格,包括空格在内的姓氏将转到列表的下一个元素。带或不带的 fflush(stdin) - 与字符串之前的问题相同的 o/p。
    • 好的.. 谢谢迈克.... 阅读您编辑的评论后,我明白了这个问题的想法... 干杯
    • @GauravK - 好吧,您没有提到您想在输入中占用一个空格:P 请参阅我对如何在 scanf() 中占用一个空格进行的编辑
    • 但我想接受名字、中间名和姓氏之间的空格。 scanf() 不能做到这一点。那我该怎么办?
    • @Mike..scanf("%[^\n]",info->name);为第二个和第三个元素转义了名称条目,并为第二个和第三个元素产生了奇怪的名称输出..:P
    猜你喜欢
    • 1970-01-01
    • 2022-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    • 1970-01-01
    • 2021-05-15
    相关资源
    最近更新 更多