不可预测的scanf用于读取Char类型输入的行为。

时间:2013-08-28 21:58:23

标签: c char scanf

我正在学习链表,当我使用scanf输入一个字符时,代码编译得很好,但在运行时它不会要求输入并跳过scanf语句。

#include<stdio.h>
#include<stdlib.h>
struct node
{
    int data;
    struct node *ptr;
};
struct node* allocate();
struct node* create();
void display(struct node*);
int main()
{
    struct node *new;
    new=create();
    display(new);
    return 0;
}
struct node* allocate()
{
    struct node *temp;
    temp=(struct node*)malloc(sizeof(struct node));
    return temp;
}
struct node* create()
{
    struct node *start,*next;
    char ch;
    start=next=allocate();
    printf("Enter data:\n");
    scanf("%d",&start->data);
    perror("store data");
    start->ptr=NULL;
R1: printf("Do you want to enter more data? y or n::    ");
    scanf("%c", &ch); //Check for error here
    if(ch=='y'||ch=='Y')
    {
        while(ch=='y'||ch=='Y')
        {
            next->ptr=allocate();
            next=next->ptr;
            printf("Enter data:\n");
            scanf("%d",&next->data);
            next->ptr=NULL;
            printf("Do you want to enter more data? y or n::    ");
            scanf(" %c",&ch);
        }
    }    
    if(ch=='n'||ch=='N')
    {
        return start;
    }
    else
    {
        printf("Please enter correct option.\n");
        goto R1;
    }
}
void display(struct node* temp)
{
    printf("%d\n",temp->data);
    while(temp->ptr!=NULL)
    {
        temp=temp->ptr;
        printf("%d\n",temp->data);
    }      
}

请参阅评论

  

在这里检查错误

在代码中知道我所指的陈述。

  • 现在,如果我在格式说明符之前添加一个空格,即在scanf语句中%c之前的空格,那么我的代码运行正常。

    scanf(" %c",&ch);
    

当我使用getchar而不是scanf

时,我遇到了同样的问题
ch=getchar();

当我在scanf语句中使用格式说明符之前不使用空格运行代码或使用getchar()语句时,我的程序不会要求输入。它没有储存任何东西。 任何人都可以解释一下背后的原因吗?为什么scanf对字符数据类型的表现如此不同?

其他信息:

  • 使用GCC
  • Linux Kernel 3.6.11-4
  • OS Fedora 16(64位)
  • intel i5处理器。

2 个答案:

答案 0 :(得分:2)

为什么scanf对字符数据类型的表现如此不同?

scanf()表现不同,因为类型不同。

使用数字格式说明符,例如%i%u%e%f,scanf()会丢弃前导空格。所以“123”和“123”都被读作123.

对于%c,scanf()需要1个字节的输入,任何 1 字节,并返回它,包括空格和\ 0。

使用%s scanf()就像忽略前导空格一样扫描数字。它会在chars中扫描,直到找到另一个空格。

格式说明符%[...]的工作方式与%s类似,因为它会扫描多个char,但“...”部分会说明要查找的内容。它不会抛弃领先的空白。

答案 1 :(得分:1)

 why does scanf behave so differently with character data types?

那是因为scanf表现得像那样,事实上它是一个非常复杂的功能,应该尽量避免它直到必要。然而,主要原因在于,格式字符串中的空格意味着跳过下一个输入项之前的任何空格,除了%c

因此,scanf("%d%d", &n, &m)的行为与scanf("%d %d", &n, &m)相同。对于%c,添加一个 格式字符串的空格字符确实有所不同。例如,如果%c前面有格式字符串中的空格,scanf()会跳到第一个非空白字符。也就是说,命令scanf("%c", &ch)读取输入中遇到的第一个字符,scanf(" %c",&ch)读取遇到的第一个非空白字符。

请注意,空格也是字符

根据C11标准( 7.21.6.2 fscanf功能,第8节

  

输入空白字符(由isspace函数指定)   被跳过,除非规范包含 [ c ,   或 n 说明符