鱼C论坛

 找回密码
 立即注册
查看: 1688|回复: 8

C语言scanf录入字符,字符串

[复制链接]
发表于 2023-3-23 13:30:12 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 gudanbeiying 于 2023-3-23 15:26 编辑

当用scanf录入一个字符串的时候会把最后的回车记录在缓冲区里,当下一次用scanf录入一个字符的时候会把缓冲区里的回车直接录入。
#include<stdio.h>
int main()
{
        char a[10];
        char b;
        printf("输入a:");
        scanf("%s",a);
        printf("a = %s",a);
        printf("输入b:");
        scanf("%c",&b);
        printf("b = %c",b);
    return 0;
}
这里我输入 a回车,会直接跳过b的输入,因为b直接被缓冲区的回车赋值了。

但是为什么要是我将b设置为字符数组,然后第二个scanf给b录入字符串:
#include<stdio.h>
int main()
{
        char a[10];
        char b[10];
        printf("输入a:");
        scanf("%s",a);
        printf("a = %s",a);
        printf("输入b:");
        scanf("%s",&b);
        printf("b = %s",b);
    return 0;
}
  这里我输入 aaa回车,结果为a = aaa输入b:(这里我输入bbb回车)bbb(回车),结果为b=bbb
为什么第二段代码在赋值b的时候没有被缓冲区的回车影响,可以正常输入,而且在输出b的时候也没有体现出回车符号,而只有bbb?第一次scanf输入是缓冲区留下的回车去哪了?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-3-23 13:37:50 | 显示全部楼层
本帖最后由 dolly_yos2 于 2023-3-23 13:40 编辑

因为遇到 %s 描述符会自动跳过前导空白,而 %c 不会跳过任何字符
供您参考:https://www.open-std.org/jtc1/sc ... subsection.7.23.6.2
8 Input white-space characters are skipped, unless the specification includes a [, c, or n specifier.347)
347)These white-space characters are not counted against a specified field width.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-23 13:39:49 | 显示全部楼层
问题的关键在于scanf的使用方式和字符串格式化输入的处理。

在第一个代码示例中,当你使用scanf("%c", &b)时,scanf会读取缓冲区中的下一个字符,而这个字符正好是第一次输入字符串时的回车符(换行符)。换行符会被立即读取并赋值给b,这就是为什么没有等待你输入新的字符。

在第二个代码示例中,你使用了scanf("%s", &b)。%s表示字符串输入,这里的关键区别在于字符串输入格式化会自动跳过缓冲区中的空格、制表符和换行符。所以当第二次调用scanf时,它会自动忽略缓冲区中的换行符,然后等待你输入新的字符串。当你输入"bbb"并按回车后,这个新的字符串就被赋值给b。此时,换行符在第二次scanf时已经被忽略了,因此在输出时也不会显示出来。

总结一下,当使用%c格式化输入时,scanf会立即读取缓冲区中的下一个字符,包括换行符;而当使用%s格式化输入时,scanf会自动跳过空格、制表符和换行符,直到遇到有效的字符输入。这就是为什么在第二个示例中,即使缓冲区中有换行符,也能正常输入字符串。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-3-23 13:58:52 | 显示全部楼层
isdkz 发表于 2023-3-23 13:39
问题的关键在于scanf的使用方式和字符串格式化输入的处理。

在第一个代码示例中,当你使用scanf("%c", & ...

懂了懂了,我还想问就是,我在做PAT考试题的时候,在我用scanf录入了一个整型变量的前提下比如 5回车,然后下面我要给字符型数组录入字符串,我用scanf %s,系统就不给我判满分,但是我把scanf换成,getchar();先清理掉缓冲区的回车,然后用gets()录入字符串就是满分,那scanf写法没啥问题呀,为啥就不是满分呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-23 14:00:56 | 显示全部楼层
gudanbeiying 发表于 2023-3-23 13:58
懂了懂了,我还想问就是,我在做PAT考试题的时候,在我用scanf录入了一个整型变量的前提下比如 5回车,然 ...

在PAT考试题中,这个问题可能是由于缓冲区处理和输入格式的不同要求导致的。当你使用scanf读取一个整型变量后,缓冲区中的换行符没有被消耗,所以下一个scanf读取字符串时可能会受到影响。虽然scanf("%s")会自动跳过空格、制表符和换行符,但在实际评测环境中,输入和换行符的处理可能有所不同,这可能导致了你的解答没有得到满分。

当你使用getchar()清空缓冲区后再使用gets()读取字符串,你手动处理了缓冲区中的换行符。这样可以确保在读取字符串时,不会受到先前输入整数时留在缓冲区的换行符的影响。因此,这个解决方案在评测系统中可以得到满分。

在实际编程中,为了避免类似问题,你可以在需要的时候使用getchar()或者其他方法清空缓冲区。这可以确保你的输入不会受到先前输入遗留在缓冲区的字符的影响。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 0 反对 1

使用道具 举报

发表于 2023-3-23 14:13:30 From FishC Mobile | 显示全部楼层
本帖最后由 dolly_yos2 于 2023-3-23 14:15 编辑
gudanbeiying 发表于 2023-3-23 13:58
懂了懂了,我还想问就是,我在做PAT考试题的时候,在我用scanf录入了一个整型变量的前提下比如 5回车,然 ...


会不会这个要录入的字符串可能含有空格等空白字符? %s 会在遇到这类字符时停止,而 fgets 会读入直到遇到换行符或达到输入数量限制。这两种函数的行为是不同的
另外已经不止是不建议使用 gets 了,这一函数在新版本的 C 语言中已经被删除了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-3-23 15:32:27 | 显示全部楼层
dolly_yos2 发表于 2023-3-23 14:13
会不会这个要录入的字符串可能含有空格等空白字符? %s 会在遇到这类字符时停止,而 fgets 会读入直到 ...

不太清楚,这个题没涉及到文件呀,fgets不是从文件中录入吗,我作题的时候这两种写法的运行结果完全一样,各种情况也都没问题,我自己也调试过在缓冲区有回车的时候,下面用scanf录入字符串,确实不会把回车录到字符串内,但考试系统就是不给这个scanf写法打满分
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-23 15:35:55 From FishC Mobile | 显示全部楼层
gudanbeiying 发表于 2023-3-23 15:32
不太清楚,这个题没涉及到文件呀,fgets不是从文件中录入吗,我作题的时候这两种写法的运行结果完全一样 ...

标准输入也是文件(stdin)
我指的情况是这个字符串里面有空格,可以试一下用 scanf 读入带空格的字符串看看是什么效果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-3-23 15:48:13 | 显示全部楼层
dolly_yos2 发表于 2023-3-23 15:35
标准输入也是文件(stdin)
我指的情况是这个字符串里面有空格,可以试一下用 scanf 读入带空格的字符串 ...

带空格的话就只会录入空格之前的,比如 aaa bbb就只会录入aaa
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-7 17:32

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表