编程中国 | 业界新闻 | 技术文章 | 视频教程 | 下载频道 | 程序源码 | 个人空间 | 编程论坛  
全能 ASP / PHP / ASP.NET 主机,支持月付专业 MSSQL 数据库空间,支持月付专业 MySQL 数据库空间,支持月付学习型 ASP/PHP/ASP.NET 主机 30元/年
 29 123
发新话题
打印

scanf函数中关于“\n”的疑惑

本主题由 卧龙孔明 于 2008-7-25 10:54 解除精华
哈哈……孔明啊……那个帖子里面你菜得可爱呢,哈哈哈~~~~~

目前认为,scanf会向下“查看”一个字符,然后判断是否接受。scanf一定会尽量大地接受合法字符。这个应该这么理解:(以下<CR>代表回车)
例一:%d(以后只写控制符),输入123<CR>
为什么会得到123呢?scanf查看1,是数字,接受,然后查看2,也接受,最后查看到你输入的回车,不是数字,不接受,所以得到123,把回车留在缓冲区里面。
例二:%d%c(或者%d%*c),输入123<CR>
这个也是常用的用法,主要用在scanf和gets混用的情况下。例一的时候,scanf把回车留在了缓冲区里面,所以如果马上调用gets,gets会得到这个scanf“不要”的回车,而读不到下面一行。所以我们用%c读取这个回车字符(%c大家都知道吧?%*c的意思是读取以后把读到的内容扔掉,不赋值给任何变量)。这样,就可以用gets读到下一行得内容了。不过这种方式对输入要求很高,如果你输入123<空格><CR>,那么gets照样得不到下一行的内容了,为什么,大家仔细思考就能知道。
例三:%d (或者%d\n),输入123<CR>
这是我们讨论的用法,注意%d后面有一个空格。这样,读取123之后,遇到回车,scanf发现不满足%d的要求了,于是查看下面一个字符,发现是空白字符(' ','\t','\n'这三个,叫空白字符)。scanf的逻辑是,遇到空白字符,则读取所有的空白字符。那么,scanf接受了回车。但是这个时候,缓冲区空了!scanf会继续等待在原地(为什么?因为没用接受到非法字符啊,scanf只有在接受到非法字符的时候才会返回)。这样就出现了LS某人说的“输入以后没反映”的情况了,这个时候,你随便输入一个非空白字符,让scanf接受到这个非法字符(为了能刷新缓冲区,别忘了输入回车哦~),比如aa<CR>,这样scanf查看到“a”这个字符,发现不满足“空白字符”这个格式,就返回了,你也得到了输入。注意,直接按回车是没有反应的,因为回车本身就是空白字符,你必须输入一个非空白字符。

大家都明白了?

这里做一个说明,就是scanf默认"%d"和" %d"是一样的,就是说scanf自动忽略掉开始读入的任何空白字符。这就解释了为什么缓冲区里面有回车,scanf仍然可以读到想要的内容的原因(就是这个原因,所以scanf和gets不好混用)。
上面第三种方法实现了scanf和gets的混用,但是觉得不爽,必须一次输入两行才能得到输出,第二种方法又对格式限制太严格,有没有更好的办法呢?
有!请使用"%d%*[^\n]%*c",这样就消掉了你输入的数字后面所有的非法字符,直到回车,然后吃掉回车字符。比如你可以输入123abc<CR>,没关系,scanf照样读取,而且缓冲区不会剩下任何垃圾。
为什么可以这么写呢?请百度。
专心编程………
飞燕算法初级群:3996098
我的Blog

TOP

不好意思,专心打字了很久,没看见孔明后面的跟帖。还有不明白的请跟帖询问。这个东西我是很熟悉了,可以为大家解释清楚。
专心编程………
飞燕算法初级群:3996098
我的Blog

TOP

那个,孔明,我还没回来,现在在上海,电脑不习惯啊,所以现在打字暴慢,555……
专心编程………
飞燕算法初级群:3996098
我的Blog

TOP

果然是个好方法,又测试了几个程序,发现再不用像以前一样处理讨厌的空格了...
为了中国软件工业的未来,有爱心的朋友请不要帮忙代做作业,或者至少是收费服务!如果您不需要钱,或者您不愿收费用于自己,请把收取的钱用于支援山区贫困学生…谢谢大家!

TOP

嘿嘿,所以现在特别喜欢C风格的格式控制,方便啊,比C++不知道方便到哪里去了~~只要你会用,就会很简单地达到你想要的结果~
专心编程………
飞燕算法初级群:3996098
我的Blog

TOP

回复 15# 卧龙孔明 的帖子

那照你这么说,我们是不是应该学习一下非洲的那些古老语言,说不定哪天会迷失在非洲的原始部落中呢,那时可能这些语言就是保命用的!

TOP

回复 6# 卧龙孔明 的帖子

没有错误

TOP

回复 12# 卧龙孔明 的帖子

你那个帖子上    说的意思和我的是完全一样的,怎么会是错误的呢/

TOP

引用:
xiaomengxia2008 在 2008-7-25 17:27 的发言:

你那个帖子上    说的意思和我的是完全一样的,怎么会是错误的呢/
你先把帖子看完再说吧
我说过了,那个贴中的我是2年前的我,我那时很菜,说的是错的,你看看softwind和我不是郭靖的回帖,然后你再看看starwing的帖子。
为了中国软件工业的未来,有爱心的朋友请不要帮忙代做作业,或者至少是收费服务!如果您不需要钱,或者您不愿收费用于自己,请把收取的钱用于支援山区贫困学生…谢谢大家!

TOP

 29 123
发新话题