关于#c语言#的问题:scanf被跳过只有通过清除缓存区才能执行

为什么第二个scanf被跳过了,换成getchar也会被跳过,只有通过清除缓存区才能执行

/* 程序名:pg9202.cpp */
/*  指针和数组及存储单元 - 冒泡排序算法 */
#include <stdio.h>

void swap2 (int *, int *);
void bubble (int a[], int n);

int main()
{    
    int n=10, a[10];
    int i;
    char ch;
    
    printf("请输入10个整数: \n");
    for (i=0; i<n;i++)
        scanf("%d",&a[i]);
               
    printf("请输入选项:\n");
    printf("D.自大到小\tA.自小到大\n"); 
    //fflush(stdin);//加上这个函数才能执行
    scanf("%c", &ch);//就是这里!!
    
    printf("排序后的数据为:\n");
    bubble (a, n) ;
    if(ch=='D')
    {
    for (i=0; i<n; i++)
        printf("%3d",a[i]);
    printf("\n");
    }
    if(ch=='A')
    {
    for (i=n-1; i>=0; i--)
        printf("%3d",a[i]);
    printf("\n");
    }
    
}

void bubble (int a[], int n)          
{
    int  i, j;
    for( i=1; i<n; i++)        
        for (j=0; j<n-i; j++ )    
            if (a[j]>a[j+1])        
                swap2(&a[j], &a[j+1]);    
}



void swap2 (int *px, int *py)
{
    int t;
    t = *px; 
    *px = *py; 
    *py = t;
}

第21行: scanf("%c", &ch);//就是这里!! 修改为: scanf(" %c", &ch); ,“ %c” 引号 “ 与 %c 间留一空格。

这个问题是源于 scanf 在读取了换行符 \n 之后并不会分配到参数里,会调用 ungetc 把这个换行符推回到 stdin 里,因此,当调用 scanf("%c") 时,就会直接将存于 stdin 的换行符都进去,从而直接跳过本来应该有的输入。
大部分情况下这不是一个问题,因为除非读取字符,不然都会跳过换行符。
而之所以调用 fflush 可以解决这个问题,是因为 fflush 本身具有取消所有 ungetc 的功能,所以之前 ungetc 推回的换行符无效。
解决方案挺多的,你注释的就是一个。在 scanf 之前调用 getchar 把换行符读掉也是可行的;也可以在 scanf("%c") 的前面加上 "\n" 或者 " "(空格),变成 "\n%c" 或 " %c"。

【以下回答由 GPT 生成】

解决方案:

在C语言中,遇到scanf等输入函数被跳过的情况,很可能是因为输入缓冲区中还有残留的换行符或空格字符。这些残留字符会被当作有效输入导致scanf跳过。为了解决这个问题,我们可以使用以下两种方法之一:

方法一:清除输入缓冲区

在第一个scanf后,如果有残留的换行符或空格字符,我们需要使用getchar函数来清除输入缓冲区。

代码如下所示:

// 清除输入缓冲区
while (getchar() != '\n')
    continue;

将这段代码添加到第一个scanf函数之后即可。

更新后的代码如下:

/* 程序名:pg9202.cpp */
/* 指针和数组及存储单元 - 冒泡排序算法 */
#include <stdio.h>

void swap2(int *, int *);
void bubble(int a[], int n);

int main()
{
    int n = 10, a[10];
    int i;
    char ch;

    printf("请输入10个整数: \n");
    for (i = 0; i < n; i++)
        scanf("%d", &a[i]);

    // 清除输入缓冲区
    while (getchar() != '\n')
        continue;

    printf("请输入选项:\n");
    printf("D.自大到小\tA.自小到大\n");
    scanf("%c", &ch);

    printf("排序后的数据为:\n");
    bubble(a, n);
    if (ch == 'D')
    {
        for (i = 0; i < n; i++)
            printf("%3d", a[i]);
        printf("\n");
    }
    if (ch == 'A')
    {
        for (i = n - 1; i >= 0; i--)
            printf("%3d", a[i]);
        printf("\n");
    }
}

void bubble(int a[], int n)
{
    int i, j;
    for (i = 1; i < n; i++)
        for (j = 0; j < n - i; j++)
            if (a[j] > a[j + 1])
                swap2(&a[j], &a[j + 1]);
}

void swap2(int *x, int *y)
{
    int temp;
    temp = *x;
    *x = *y;
    *y = temp;
}

方法二:使用fgets函数替代scanf

另一种常用的解决方法是使用fgets函数来读取输入,并将输入存储到一个字符串中。然后使用sscanf函数从该字符串中解析出所需的数据。

代码如下所示:

char input[100];
fgets(input, sizeof(input), stdin);
sscanf(input, "%c", &ch);

将这段代码添加到第二个scanf函数之前即可。

更新后的代码如下:

/* 程序名:pg9202.cpp */
/* 指针和数组及存储单元 - 冒泡排序算法 */
#include <stdio.h>

void swap2(int *, int *);
void bubble(int a[], int n);

int main()
{
    int n = 10, a[10];
    int i;
    char ch;
    char input[100];

    printf("请输入10个整数: \n");
    for (i = 0; i < n; i++)
        scanf("%d", &a[i]);

    printf("请输入选项:\n");
    printf("D.自大到小\tA.自小到大\n");

    fgets(input, sizeof(input), stdin);
    sscanf(input, "%c", &ch);

    printf("排序后的数据为:\n");
    bubble(a, n);
    if (ch == 'D')
    {
        for (i = 0; i < n; i++)
            printf("%3d", a[i]);
        printf("\n");
    }
    if (ch == 'A')
    {
        for (i = n - 1; i >= 0; i--)
            printf("%3d", a[i]);
        printf("\n");
    }
}

void bubble(int a[], int n)
{
    int i, j;
    for (i = 1; i < n; i++)
        for (j = 0; j < n - i; j++)
            if (a[j] > a[j + 1])
                swap2(&a[j], &a[j + 1]);
}

void swap2(int *x, int *y)
{
    int temp;
    temp = *x;
    *x = *y;
    *y = temp;
}

以上两种方法都可以解决scanf函数被跳过的情况。你可以根据个人的喜好和实际需求选择其中一种方法。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^