首页 > 编程知识 正文

c语言关键字scanf,c语言里scanf是什么意思

时间:2023-05-05 07:25:15 阅读:151450 作者:3977

8种机械键盘轴体的比较

本人要买写代码的键盘,红轴和茶轴怎么选?

我在大学学的第一门语言是c语言,几年在OJ用c语言提出了成百上千个主题,但我甚至不知道最基本的scanf函数的使用方法。 遇到几个字符串和数字混合输入的主题,几乎只能通过推测输入……这次我们来具体看看scanf函数的使用方法。

scanf函数介绍信息来自私人教程

说明

C库函数intscanf(constchar*format,)从标准输入stdin中读取格式输入。

发表声明

scanf ) )函数的声明如下。 1int(constchar*format,) ) )。

参数format-这是一个c字符串,其中包含一个或多个空白字符、非空白字符和format说明符。

format说明符的格式为[=%[*][width][modifiers]type=],具体说明如下: 参数说明*这是一个可选的星号,从流stream读取了数据,但可以忽略。 这意味着它不存储在相应的参数中。

width指定当前读取操作中读取的最大字符数。

modifiers为相应附加参数指向的数据指定整数(对于d、I、n )、无符号整数(对于o、u、x )或浮点(对于e、f、g )的大小。 h :短整数)、d、I、n时)、或无符号短整数)、o、u、x时) l :长整数

type是指定要读取的数据类型和读取数据的方式的字符。 具体请参照下表。

scanf类型说明符:通过类型的输入参数的类型c单词:读取下一个字符。 如果指定宽度为1以外的width,则函数读取width字符,并通过传递参数将其存储在数组中的连续位置。 末尾不添加空白字符。 char *

d10进制整数:数字前面的或-符号是可选的。 int *

e、e、f、g、g浮点数:包含小数点、可选前置或-、可选后置字符e或e以及十进制数。 两个有效实例-732.103和7.12 E4浮点*

o8进制整数。 int *

s字符串。 这会读取连续的字符,直到找到空白字符。 空白字符包括空白、换行符、制表符等。 char *

无u形符号的十进制整数。 unsigned int *

x,x16进制整数。 int *附加参数根据格式字符串,函数可能需要一组附加参数。 每个参数包含插入的值,而不是在format参数中指定的每个%标记。 参数的个数必须与%标签的个数相同。

返回值

如果成功,函数返回成功匹配和赋值的数量。 如果到达文件末尾或发生读取错误,则返回EOF。

使用

说实话,私人教程的这个文档也不容易读。 因为基本上是直接翻译的东西(原始文档)……所以在一些地方翻译得不好。 要知道具体的使用方法,还是要实际打一下。

在OJ中使用

OJ评价原理

关于OJ评价的具体原理,我稍后会写博客进行说明。 这里只说明评价时的输入输出问题。

OJ评估使用输入文件替换被评估程序的标准输入,并通过比较程序的标准输出和输出文件来确定执行结果。

scanf读取数据的原理

如文档中所述,scanf从标准输入流stream中读取数据。 我们认为,在评估开始时,一次将所有输入数据扔到标准输入流的缓冲池中。 这时,可以将整个标准输入流量看成一个输入数据的字符串,读取数据是根据某个规则从该字符串中分析自己想要的数据。

读取时,包含指向要在输入数据字符串中读取的下一个字符的指针。 我们应该做的是正确读取所有的数据。

scanf函数在读入时每当遇到类型说明符时,都会尝试与指针所指的文字一致,在读入符合规则的所有文字后,将解析的数据存在于用户指定的变量中。

那么,我能知道怎么读取符合规则的文字吗? scanf在读取达到宽度限制==为了读取3位数字的条件下进行判断

遇到了“针对当前类型说明符”的非法输入,例如%d读取“a”

scanf遇到以上条件时停止当前匹配,开始下一个类型说明符的匹配。

具体例子

例如,1

2

3

4char ch;

char str[100];

scanf('%c%s )、ch和str );

printf(ch:%cnstr:%s )、ch和str ); 1

2

3问候世界

d!

>ch: H

str: elloWorld!

在程序开始运行的时候,标准输入流中的字符串为 "HelloWorld!" ,scanf 首先尝试匹配 '%c' :1

2HelloWorld!

^

'%c' 匹配了指针指向的字符 'H' ,指针后移一位,长度达到限制, '%c' 停止匹配。1

2HelloWorld!

^

此时 scanf 尝试匹配 '%s' , '%s' 的匹配规则为:匹配连续字符,直到遇到空白符(空格、换行或者格式制表符等)。 '%s' 成功匹配该行剩下的所有字符 "elloWorld!" ,并将其存到字符数组 str 中。

另一个例子:1

2

3

4char ch;

char str1[100], str2[100];

scanf("%c%s%s", &ch, str1, str2);

printf("ch: %cnstr1: %snstr2: %sn", ch, str1, str2);1

2

3

4Hello World!

>ch: H

str1: ello

str2: World!

当 ch 和 str1 读取结束的时候,指针的位置如下:1

2Hello World!

^

那为什么 str2 读取到的却是 "World!" 呢?原因很简单,因为 '%s' 类型说明符在匹配的时候会忽略字符串开头所有的空白符,指针会一直后移直到指向 'W' 的时候才正式开始匹配。

同样的程序,我们换一组输入:1

2

3

4

5Hello

World!

>ch: H

str1: ello

str2: World!

原理同上,在字符串中,换行和其他空白符没有本质上的区别,读取的字符串实际上是: "HellonWorld!" ,对于 'n' 的处理和对其他空白符的处理是一样的,因此会出现和上面的程序一样的结果。

但是如果我们把上面程序的格式说明符交换一下位置的话就会出现问题:1

2

3

4char ch;

char str1[100], str2[100];

scanf("%s%c%s", str1, &ch, str2);

printf("ch: %cnstr1: %snstr2: %sn", ch, str1, str2);1

2

3

4

5

6Hello

World!

>ch:

str1: Hello

str2: World!

ch 读取到了个空?并不是, 在 str1 读取结束的时候,指针刚好指到第一行的最后: 'n' ,'%c' 在读取的时候可不管三七二十一,只要它上场,就会读取当前指针所指的那个字符,因此, '%c' 实际上是把第一行末尾的 'n' 给读取走了。因为 'n' 在控制台下会表现为一个换行,因此会给人一种什么也没有读取到的感觉。

[空格] 的使用

在使用 OJ 的过程中,绝大部分人(我认识的所有人)都曾经被数据中的不可见字符给坑过,其中,每行末尾的换行符可以说卡死过无数人。其实,只要明白了换行符也只不过是一个空白符,稍加注意,就可以避免这些问题。但是,有时候问题并非出现在我们身上,也有可能是数据的锅(POJ 某题曾经卡过我很久,最后发现是他数据中有多余的空格),那这时候我们就要尽量的提高我们代码的鲁棒性,在数据有一些问题的情况下,依然能够尽量正确的读取数据。

那么,在哪里才能买到……啊不是,我们要怎么做呢?

其实,仔细看一下文档,就会发现一个神奇的格式说明符,就是 [空格] 。在菜鸟教程翻译的文档中,只是提到了有空格这个说明符,对其作用却并没有说明。查看英文文档,我发现,[空格] 这个格式说明符可以在很大程度上避免因不可见字符而读取到错误的结果。

[空格] 的作用:读取 0 个、 1 个或多个连续的空白字符。

从描述上就可以看出,如果不是主动想要读取空白字符,那么在原有的格式说明符两侧加 [空格] 是不会产生任何问题的,而且还可以完美避免因空白字符而导致的锅。1

2

3

4char ch;

char str1[100], str2[100];

scanf("%s %c %s", str1, &ch, str2);

printf("ch: %cnstr1: %snstr2: %sn", ch, str1, str2);1

2

3

4

5Hello

World!

>ch: W

str1: Hello

str2: orld!

加上 [空格] 之后,产生了期望的结果。

(其他空白符有同样的效果,但是空白符最顺手)

总结多看英文文档比啥都好

在格式说明符两侧加空格能有效增强 OJ 体验

以上就是我对 scanf 函数的理解,如果有什么不对的或者纰漏,还请斧正,如果能对你有些许的帮助,也希望你能给我留个言~

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。