超详解 - 如何理解C语言中while(scanf(“%d“, &num) != EOF)这一表达式?

这篇具有很好参考价值的文章主要介绍了超详解 - 如何理解C语言中while(scanf(“%d“, &num) != EOF)这一表达式?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

许多C语言初学者常常对scanf函数、表达式scanf("%d", &num) != EOF的含义与其使用情况有些疑惑。

本文通过一道牛客网例题,对该表达式进行说明和适当拓展;不需要引例的朋友可以直接跳转到讲解部分。

希望对诸位读者有所帮助。

目录

一、引例 - 牛客网OJ题

二、EOF 与 scanf 函数的关系

1. EOF (End Of File)   

2. scanf 函数    

scanf 演示 

三、while(scanf("%d", &num) != EOF)的使用

四、总结


一、引例 - 牛客网OJ题

为了更好地说明这个表达式,我们以一道牛客网的题目作引例。题目链接贴在这里:牛客网习题-BC49 判断两个数的大小关系https://www.nowcoder.com/practice/f05358b9e8164b27871c87d3097f4dab?tpId=107&&tqId=33330&rp=1&ru=/ta/beginner-programmers&qru=/ta/beginner-programmers/question-ranking

题干如下

c语言 while(scanf),C语言,c语言,学习,c++,经验分享

这道题的题意非常简单,思路也非常明确,程序大体仅需简单的 if 分支即可实现。经过一番思考咱们自信地写下如下代码:

/*Wrong!*/
#include<stdio.h>

int main(){
    int x,y;
    scanf("%d %d",&x,&y);
    if(x > y)
        printf("%d>%d",x,y);
    else if (x = y)
        printf("%d=%d",x,y);
    else
        printf("%d<%d",x,y);
    return 0;
}

然而将该代码提交给牛客网OJ,却无法通过所有用例:

c语言 while(scanf),C语言,c语言,学习,c++,经验分享

说明告诉我们,当用例连续输入多组(3组)时,上面的代码没法做到一口气输出这3组用例相应的答案,而仅仅是输出了第一个用例(1 1)的答案。显然,上面的程序 scanf 在读取了一组输入用例后就跑路了,无法做到题干要求的能输入 “多组输入数据” 。我们的答案程序被毙了。

也许循环可以解决上面的bug,于是咱们尝试以下代码:

/*Wrong!*/
#include<stdio.h>

int main(){
    int x,y;
    for(int i=0; i<3; i++){
        scanf("%d %d",&x,&y);
        if(x > y)
            printf("%d>%d\n",x,y);
        else if (x == y)
            printf("%d=%d\n",x,y);
        else
            printf("%d<%d\n",x,y);
    }
    return 0;
}

试图用 for 循环来达到 “输入多组用例” 的要求。 事实上也不可行,该程序的逻辑是:输入一组用例,执行这一组用例,再通过 for 循环再输入一组用例,再执行……并不是一次性输入多组用例且同时打印多组答案。

因而,本题能被牛客网OJ通过的关键是能做到多组输入。如何实现,用到的就是我们今天要讲解的重点:while(scanf("%d", &num) != EOF)

如下是该题的一个正确答案(事实上所有的正确答案都大同小异,且EOF这句表达式是必不可少的)

#include<stdio.h>

int main(){
    int a,b;
    while((scanf("%d%d",&a,&b)) != EOF){    //重点在此!
        if(a == b)
            printf("%d=%d\n",a,b);
        else if(a > b)
            printf("%d>%d\n",a,b);
        else
            printf("%d<%d\n",a,b);
        }
    return 0;
}

 二、EOF 与 scanf 函数的关系

1. EOF (End Of File)   

名称是文件结束标志,定义为 -1(不是ASCII码值为-1),可以通过 Ctrl+Z 直接键入。

2. scanf 函数    

scanf函数是有返回值的。

一般来说,它的返回值是成功读取的元素个数。但当遭遇读取失败时,它的返回值便是 -1 (也就是它自己返回一个EOF) 。

而若是一个元素都还没成功读入的时候就遇到了读取失败或EOF,那它直接就会返回-1,不管后面再输入了什么。

Cplusplus官网对 scanf 函数的说明如下:

c语言 while(scanf),C语言,c语言,学习,c++,经验分享

by the way,  getchar()函数读取失败时,也会返回EOF。

下面这个网站建议大家收藏,C语言中各种函数、关键字等等的用法都可以在其中查询到。

Cplusplus官网https://cplusplus.com/

scanf 演示 

代码

int main(){
	int a = 0;
	int b = 0;    //输入a和b
	int ret = scanf("%d %d",&a,&b);    //用ret接受scanf的返回值
	printf("ret = %d\n",ret);
	printf("a = %d\n",a);
	printf("b = %d\n",b);
	return 0;
}

运行结果

(1) 输入 a 为7,b 为8,二者被scanf成功读取,ret为2(成功读取的元素个数)。  

c语言 while(scanf),C语言,c语言,学习,c++,经验分享

(2) 输入 a 为7,b为EOF(先键盘敲Ctrl+Z后再enter),ret变成了1,因为只有a是成功被读取的,b并没有被成功读入。

c语言 while(scanf),C语言,c语言,学习,c++,经验分享

(3)输入a为EOF,b为8,ret变成了-1(即EOF).因为scanf在一个元素也没有读取的时候就遇到了EOF(就是我们输入的a,我们人为的输入了EOF),scanf直接返回-1,程序结束。

c语言 while(scanf),C语言,c语言,学习,c++,经验分享

(4) 输入a或b为非数字,属于元素类型不匹配的情况。

第一个元素'A'并没有被读入,scanf()会停留在那,并把字符'A'放回缓冲区再又继续读取。下一次读取的时候,仍然是从'A'开始。事实上,scanf()一直无法越过'A'读到下一个字符,一直反复读入,并陷入了死循环。在如下程序中,scanf会直接认为读取结束了,跳出函数。

因而该程序终止后,一个元素也没有被读进去,但又不属于C语言定义下的读取失败,ret为0.

若将语句写成while(scanf("%d", &num) != EOF)这样,效果就是一直死循环。

(其实输完'A'按enter程序就会直接结束,而正常情况下敲enter仅仅是输入下一个数而已,这也是二者的一个差别。)

c语言 while(scanf),C语言,c语言,学习,c++,经验分享

(5) 输入a为7,b为'A',a在b之前成功读取了,因而ret为1. 

c语言 while(scanf),C语言,c语言,学习,c++,经验分享

 三、while(scanf("%d", &num) != EOF)的使用

当需要多组输入时,可以用该表达式控制循环入口。当人为的输入EOF时,结束循环。

代码演示

c语言 while(scanf),C语言,c语言,学习,c++,经验分享

此时我一次键入第一行的6个数字:5 6 10 10 2 3,敲enter,同时显示这三组用例的运行结果。注意:此时我的程序并没有结束!末行光标仍然在跳动,事实上我还能再接着键入几组数字!

c语言 while(scanf),C语言,c语言,学习,c++,经验分享

再又一次输入三组数并显示运行结果后,我敲下Ctrl+Z,此时控制台上显示了一个 ^Z ,说明成功输入了EOF,再按下enter,出现最下面的横线与小字,程序结束!!

我使用的IDE是小熊猫版的devc++,如果在vs 2019中,要输入三次Ctrl Z才行。这其实是vs的一个小bug 。

换成如下代码,也是可以的:

int main(){
	int a,b;
	while((scanf("%d%d",&a,&b)) == 2){
		if(a == b)
			printf("%d=%d\n",a,b);
		else if(a > b)
			printf("%d>%d\n",a,b);
		else
			printf("%d<%d\n",a,b);
	}
	return 0;
}

while((scanf("%d%d",&a,&b)) == 2) 与  while(scanf("%d", &num) != EOF) 本质上等价。


四、总结

本文详细介绍了scanf 与 EOF 的含义与使用。

1. 当需要多组输入时,使用while(scanf("%d", &num) != EOF)控制循环入口。

2. 初学阶段了解如何使用即可:可以将EOF直接理解为一个简单的标记。当我们在scanf函数中输入CTRL + Z时,就能“召唤”出这个标记,从而结束 scanf 函数,达到控制循环的目的。

3. while((scanf("%d%d",&a,&b)) == 2) 与  while(scanf("%d", &num) != EOF)效果完全相同。

4. 感谢大家支持!如果表述不当之处,欢迎各位斧正!


2023年更新:

现在的牛客网改版升级后,默认模板中已经自带多组输入代码了~

c语言 while(scanf),C语言,c语言,学习,c++,经验分享文章来源地址https://www.toymoban.com/news/detail-714765.html

到了这里,关于超详解 - 如何理解C语言中while(scanf(“%d“, &num) != EOF)这一表达式?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C语言基础考研向】05 scanf读取标准输入超详解

    文章目录 一.scanf函数的原理 样例 问题原因 解决方法 二.多种数据类型混合输入 错误样例 正确样例   C语言未提供输入/输出,其输入和输出是通过标准函数库来实现的。C语言通过scanf函数读取键盘输入, 键盘输入又被称为标准输入 。当scanf函数读取标准输入时,如

    2024年01月22日
    浏览(46)
  • C 语言用户输入详解:scanf、fgets、内存地址解析及实用指南

    您已经学习了 printf() 函数用于在 C 语言中输出值。 要获取用户输入,可以使用 scanf() 函数: scanf() 函数接受两个参数:变量的格式说明符(在本例中为 %d )和引用运算符( myNum ),用于存储变量的内存地址。 scanf() 函数还允许进行多个输入(例如,在下面的例子中,用户可

    2024年02月03日
    浏览(60)
  • 关于【C语言】中scanf与getchar的用法和常见错误详解

    写这篇博客的起因是最近博主自己学习中总是遇到类似的错误,并曾百思不得其解。 今天分享出来是希望帮助大家在写代码时避免这些错误。话不多说,我们直接开始吧! 君兮_的个人主页 勤时当勉励 岁月不待人 C/C++ 游戏开发 我们先来看看再MSDN里对scanf的解释 - scanf 的功能

    2024年02月05日
    浏览(50)
  • 从编程语言的角度来理解正则表达式

    程序代码是对现实事物处理逻辑的抽象,而正则表达式,则是对复杂的字符匹配程序代码的进一步抽象;也就是说,高度简洁的正则表达式,可以认为其背后所对应的,是字符匹配程序代码,而字符匹配程序代码,背后对应的是字符匹配处理逻辑。 字符匹配处理逻辑,可以抽

    2024年02月09日
    浏览(46)
  • Go基础12-理解Go语言表达式的求值顺序

    Go语言在变量声明、初始化以及赋值语句上相比其先祖C语言做了一些改进,诸如: ● 支持在同一行声明和初始化多个变量(不同类型也可以) ● 支持在同一行对多个变量进行赋值 这种语法糖在给我们带来便利的同时,也可能带来一些令人困惑的问题。 Go语言之父Rob Pike在

    2024年02月09日
    浏览(58)
  • 【C语言趣味教程】(8) 标准 IO 流:输入和输出 | 标准输入 stdin | 标准输出 stdout | 详解 printf 和 scanf | 探讨 scanf 缓冲区问题和安全性问题

        🔗 《C语言趣味教程》👈 猛戳订阅!!! 0x00 引入:I/O 的概念 计算机中的输入和输出,简称 ,其中:  代表 Input,即输入。

    2024年02月09日
    浏览(51)
  • C 语言中的 switch 语句和 while 循环详解

    替代多重 if..else 语句,可以使用 switch 语句。 switch 语句用于选择多个代码块中的一个来执行 switch 表达式只会被计算一次 表达式的值与每个 case 的值进行比较 如果找到匹配,则执行相应的代码块 break 语句用于跳出 switch 块并停止执行 default 语句是可选的,如果找不到匹配的

    2024年02月04日
    浏览(38)
  • LangChain 67 深入理解LangChain 表达式语言30 调用tools搜索引擎 LangChain Expression Language (LCEL)

    LangChain系列文章 LangChain 50 深入理解LangChain 表达式语言十三 自定义pipeline函数 LangChain Expression Language (LCEL) LangChain 51 深入理解LangChain 表达式语言十四 自动修复配置RunnableConfig LangChain Expression Language (LCEL) LangChain 52 深入理解LangChain 表达式语言十五 Bind runtime args绑定运行时参数

    2024年01月23日
    浏览(83)
  • 【C语言初阶篇】 while 语句的语法和注意事项 (详解版)

    🎬 鸽芷咕 :个人主页  🔥 个人专栏 :《C语言初阶篇》 《C语言进阶篇》 ⛺️生活的理想,就是为了理想的生活!    🌈 hello! 各位宝子们大家好啊,又是新的一天开始了,今天给大家带来的循环语句的全面讲解!    ⛳️ 历时一天终于给肝出来了,本文详细讲解了wh

    2024年02月14日
    浏览(49)
  • getchar函数详解看这一篇就够了-C语言(函数功能、使用、返回值)

    首先要明确getchar的功能是:从计算机终端(一般是键盘)输入一个字符,其值就是输入得到的字符。 目录 getchar函数简介 getchar函数执行过程详解(配图)  getchar用法示例 解释一下:while ((ch=getchar()) != \\\'EOF\\\') 函数原型:int getchar(void);                                 返回

    2024年02月07日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包