【C语法学习】12

编程入门 行业动态 更新时间:2024-10-13 22:25:51

【C<a href=https://www.elefans.com/category/jswz/34/1770552.html style=语法学习】12"/>

【C语法学习】12

文章目录

  • 0 前言
  • 1 函数原型
  • 2 参数
    • 2.1 格式字符串
      • 2.1.1 转换说明
    • 2.2 参数列表
  • 3 返回值
  • 4 读取机制
    • 4.1 基本概念
    • 4.2 转换说明
    • 4.3 读取过程
    • 4.4 读取示例
    • 4.5 多参数
  • 6 示例
    • 6.1 示例1
    • 6.2 示例2
    • 6.3 示例3
    • 6.4 示例4

0 前言

scanf()函数虽然使用起来较为灵活,但是其读取机制还是有点复杂。

1 函数原型

scanf():从标准输入流stdin读取格式化输入,函数原型如下:

int scanf(const char *format, ...);

2 参数

scanf()函数的参数分为两类:

  1. format :格式字符串;
  2. … :参数列表。

2.1 格式字符串

在scanf()函数中:

  1. 格式字符串是必不可少的;
  2. 格式字符串由字面文本量、转义序列和转换说明三部分组成。

2.1.1 转换说明

  1. 格式字符串中的转换说明和参数列表在数量、顺序和类型上要完全匹配;
  2. 格式字符串中只包含转换说明即可,强烈建议不要包括字符串字面量和转义序列,但多个转换说明之间可以用空格隔开,便于阅读;
  3. 如果想从键盘获取字符,建议用getchar()函数替代%c;
  4. 如果想从键盘获取字符串,建议用gets()函数替代%s;%s会读取的字符串末尾加上空字符’\0’,作为字符串结束符;
  5. 与printf()函数不同,在scanf()函数中,%f对应float类型变量,%lf对应double类型变量。

2.2 参数列表

在scanf()函数中:

  1. 参数列表是必不可少的;
  2. 参数列表中参数的数量是可变的,但至少应包含一个参数;
  3. 参数列表中参数的类型是指针类型(&变量名)。

3 返回值

scanf()函数的返回值类型为int型:

  1. 读取成功,返回成功读取的项数;
  2. 读取失败,返回EOF。

C语言标准描述如下:

1. Both scanf and wscanf return the number of fields successfully converted and assigned; the return value does not include fields that were read but not assigned. A return value of 0 indicates that no fields were assigned. 
2. The return value is EOF for an error or if the end-of-file character or the end-of-string character is encountered in the first attempt to read a character.

4 读取机制

4.1 基本概念

  1. 键盘输入:从键盘输入的都是文本,因为键盘只能生成文本字符:字母、数字和标点符号;
  2. 空白字符:空格、制表符和换行符。

4.2 转换说明

转换说明不同,有效字符也不同:

  1. %d转换说明要求scanf()函数能识别十进制数0-9和正负号±;
  2. %x转换说明要求scanf()函数能识别十六进制数a-f和A-F;
  3. %f转换说明要求scanf()函数能识别小数点、e计数法和p计数法等;
  4. %s转换说明要求scanf()函数能识别除空白字符外的所有字符。

4.3 读取过程

scanf()函数读取标准输入流stdin过程如下:

  1. 在遇到第一个非空白字符前,所有的空白字符被读出且被丢弃;
  2. 从遇到第一个非空白字符始,直至
    (1)遇到无效字符:在遇到的第一个无效字符处停止读取,并将无效字符退回至标准输入流stdin中;
    (2)遇到空白字符:在遇到的第一个空白字符处停止读取,并将空白字符退回至标准输入流stdin中;
    (3)达到指定字段宽度:如果使用字段宽度修饰符,在有效字符数达到指定字段宽度处停止读取;
  3. 读取结束后对已读取的有效字符按照转换说明进行转换,然后储存在指定变量中。

特别说明:使用scanf()函数之后一定要清空标准输入流stdin。

4.4 读取示例

以scanf(“%d”, &num)为例:

  1. scanf()函数从标准输入流stdin中读取字符,跳过前面所有的空白字符,从第一个非空白字符开始,直至
    (1)遇到无效字符,将无效字符退回至标准输入流stdin中,读取结束;
    (2)遇到空白字符,将空白字符退回至标准输入流stdin中,读取结束;
    (3)达到指定字段宽度,读取结束;
  2. 将已读取的有效字符按照转换说明要求进行转换,并储存在指定的变量num中;

问题:如果第一次读到的非空白字符是无效字符(如字母a),会发生什么情况呢?

解答:如上所述,如果读到字母a,则立即停止读取,并将字母a退回stdin中,那么本次读取就未读到任何有效的字符,也就是说本次读取是失败的,不会有任何值储存在变量num中,scanf()函数的返回值为0。

4.5 多参数

参数列表中的多个参数对应格式字符串中的多个转换说明:

  1. 用空白字符将键盘输入分成多个字段;
  2. 字段间可以有多个空白字符,多个空白字符集中在一行或分散在多行;
  3. 多个字段与多个转换说明;
  4. 唯一例外的是%c转换说明:根据%c,scanf()函数会读取每个字符,包括空白字符。

6 示例

6.1 示例1

scanf()函数读取过程中的丢弃和回退,代码如下所示:

int main ()
{//定义变量int a;char str[80] = {0};//给变量a赋值,输入2个空格+12a+2个空格+Enterscanf("%d", &a);//打印变量a的值printf("a=%d\n", a);//用gets清空stdingets(str);//打印str的内容和长度printf("str = %s, len = %d\n", str, strlen(str));return 0;
}

代码执行结果如下图所示:

代码及运行结果分析:
第一阶段:

  1. 标准输入流中有字符:2个空格+字符12a+2个空格+回车符共8个字符;
  2. scanf()函数读取前两个空格并丢弃;
  3. scanf()函数读取字符1和2,转换为数值12后储存在变量a中;
  4. scanf()函数读取字符a,发现a是无效字符,将a回退至标准输入流stdin中;
  5. 至此scanf()函数从标准输入流stdin中读取完毕;

第二阶段:
6. gets()函数继续从标准输入流stdin中读取字符串;
7. 因标准输入流stdin中仍残留有scanf()函数未读完的字符,故无需用户再次从键盘键入字符;
8. gets()函数会读空标准输入流stdin中的所有字符,直至遇到回车符’\n’;

第三阶段:
9. printf()函数打印a和str的内容,并统计str的长度;a=12符合预期;str长度为3符合预期,即字符’a’+2个空格。

6.2 示例2

scanf()函数返回值,代码如下所示:

void clear_stdin(void)
{while (getchar() != '\n');
}int main()
{//变量定义int a = 0, b = 0, c = 0;int num = 0;//第1次输入puts("输入11 22 33 : ");num = scanf("%d%d%d", &a, &b, &c);clear_stdin();printf("a=%d, b=%d, c=%d, num=%d\n\n", a, b, c, num);//第2次输入puts("输入44 55 a6 : ");num = scanf("%d%d%d", &a, &b, &c);clear_stdin();printf("a=%d, b=%d, c=%d, num=%d\n\n", a, b, c, num);//第3次输入puts("输入77 a8 99 : ");num = scanf("%d%d%d", &a, &b, &c);clear_stdin();printf("a=%d, b=%d, c=%d, num=%d\n\n", a, b, c, num);//第4次输入puts("输入a0 11 22 : ");num = scanf("%d%d%d", &a, &b, &c);clear_stdin();printf("a=%d, b=%d, c=%d, num=%d\n\n", a, b, c, num);return 0;
}

代码执行结果如下图所示:

代码及运行结果分析:

  1. scanf()函数在%d转换说明下,希望从标准输入流stdin中读取数字字符0-9和正负符号(±),当读取到非数字字符’a’时,将’a’退回至标准输入流stdin中,并停止读取;理论分析和num的实际打印结果相符合。

6.3 示例3

scanf()函数读取字符%c,代码如下所示:

void clear_stdin(void)
{while (getchar() != '\n');
}int main()
{//变量定义char c1 = 0, c2 = 0, c3 = 0;//第1次输入puts("输入字符abc,中间不加空格 : ");scanf("%c%c%c", &c1, &c2, &c3);clear_stdin();printf("c1=%c, c2=%c, c3=%c\n\n", c1, c2, c3);//第2次输入puts("输入字符a b c,中间加空格 : ");scanf("%c%c%c", &c1, &c2, &c3);clear_stdin();printf("c1=%c, c2=%c, c3=%c\n", c1, c2, c3);return 0;
}

代码执行结果如下图所示:

代码及运行结果分析:

  1. scanf()函数在%c转换说明下会读取键盘键入的每一个字符,包括空白字符。

6.4 示例4

scanf()函数读取字符串%s,代码如下所示:

void clear_stdin(void)
{while (getchar() != '\n');
}int main()
{//变量定义char str[80] = { 0 };//puts("输入hello world");scanf("%s", str);clear_stdin();puts(str);return 0;
}

代码执行结果如下图所示:

代码及运行结果分析:

  1. scanf()函数在读取字符的时候,如果遇到空白字符,则停止读取,所以%s只能读取单词,不能读取句子。

更多推荐

【C语法学习】12

本文发布于:2023-11-30 09:12:43,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1649473.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:语法

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!