【问题标题】:Linked list trouble链表麻烦
【发布时间】:2023-03-22 15:36:01
【问题描述】:

有谁知道以下代码可能有什么问题?当我运行它时,我得到以下输出:

Insert a value in the list: 1
Do you want to continue? y/N: 
 1 ->

事实上,do-while 循环一直执行到scanf("%c", &ch) 语句,然后它跳出(所以我无法为ch 变量提供任何输入)。我尝试使用 GDB 进行调试,但收到了一些奇怪的消息:

GI___libc_malloc (bytes=16) at malloc.c:malloc.c: No such file or directory. 

另外,它说编译器找不到vscanf.c 文件。有人对这种奇怪的行为有解释吗?谢谢! (目的是以相反的顺序打印单链表的值。)

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

struct node{
    int info;
    struct node* next;
};

struct node* head = 0;

void add_node(int value){

     struct node* current = malloc(sizeof(struct node));
     current->info = value;
     current->next = head;
     head = current;
 }

void print_node(struct node* head){

     while(head){

          printf(" %d -> ", head->info);
          head = head->next;
     }

     printf("\n");
 }

int main(void){

    int val;
    char ch;

    do {

       printf("Insert a value in the list: ");
       scanf("%d", &val);
       add_node(val);
       printf("Do you want to continue? y/N: ");
       scanf("%c", &ch);

    } while(ch == 'y' || ch == 'Y');

    printf("\n");
    print_node(head);
    return 0;
 }

【问题讨论】:

  • 这里是一个完整的镜头,第二个scanf 可以换行吗?
  • 更改 add_node 的方法签名以接受 struct node* 参数,然后将 head 的地址作为参数传递给您的函数调用。应该这样做。
  • GDB 消息通知您不能进入 GLIB 文件,只需按 c 继续。

标签: c list linked-list


【解决方案1】:

如果您希望输入由新行分隔(您似乎这样做),然后更改您在角色中阅读的格式。更改以下内容:

scanf( "%c", &ch );

...到这个:

scanf( "\n%c", &ch ); // << Note, \n to pickup newline before reading the value.

【讨论】:

  • 如果这确实是问题所在,他不能只做scanf("%d\n", &amp;val); 而不是做两个scanfs 吗?
  • 当你执行scanf("%d\n", &amp;val);时,程序会等待输入以外的内容,输入内容后它只是打印并退出。
  • @Jacob,我得到了使用'\n' 的想法,谢谢。但是,据我所知 scanf() 忽略 '\n' 字符。我错了吗?
  • @ErcanOzturk,不,我在 27 分钟前建议将其作为解决方案,但是我有一大块代码。我决定在我的编辑中删除巨大的代码块,而不是更改我的解决方案——查看历史记录。
  • @ErcanOzturk 我想我只是想知道 scanf 的规范中是否有这方面的内容,我不会感到非常惊讶。
【解决方案2】:

您可以检查 if-else 块中的正确输入,并相应地执行您的代码。 例如,如果我需要检查用户是否想继续,我会这样做:

char chTemp; //Declare a test variable to check for newline
printf("Do you want to continue? y/N: ");
if (scanf("%c%c",&ch,&chTemp) != 2 || chTemp != '\n')
{
     printf("Error in input (Integer input provided)");
}
else
{
     //Do stuff.
}

它不仅可以解决您的问题,还可以检查粗心的整数输入。

【讨论】:

    【解决方案3】:

    您遇到的问题是因为一旦您为val 键入一个值,然后按回车键,那么\n 仍然保留在输入缓冲区中。因此,下一个scanf 假定仍在输入缓冲区中的\n 是它的输入,并消耗它然后循环退出。

    其他解决方案:-

    1)scanf("%d%*c",&amp;val);

    这会将第一个输入字符分配给val,然后将其后的任何内容都吃掉。因此,\n 不会进入下一个scanf

    2)scanf("%[^\n]%*c",&amp;val);

    这会将除\n 之外的所有内容分配给val,然后\n 将被吃掉。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-24
      • 2017-03-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多