[C语言]

scanf函数不太理解,求大神帮助

[复制链接]
801|14
手机看帖
扫描二维码
随时随地手机跟帖
yanghelovehuang|  楼主 | 2018-7-5 15:07 | 显示全部楼层 |阅读模式
本帖最后由 一路向北lm 于 2018-7-8 16:31 编辑

各位大神好,小弟遇到个问题有点费解,请大神帮忙解答,程序不多,请大家看看,很简单:
int main(void)
{
        int n, a;

        while(1)
        {
                if((a = scanf("%d", &n)) == EOF)
                {
                        printf("input error\n");

                        return -1;
                }
                else if(a != 1)
                {
                        printf("excuse me!! please enter the correct number\n");
                }
        }

}


我的目的是输入一个数字,如果不是数字则重新输入,直到输入是数字为止。我觉得这段代码能够实现,如过输入不是数字就会返回到while开头scanf重新输入,可是我编译运行,故意输入字母,可是没让我重新输入而是循环打印excuse me!! please enter the correct number。
这是怎么回事啊各位大神,不应该是循环到头部scanf继续输入吗? 如果这样不行那怎么实现我想要循环输入的功能呢?

相关帖子

梦幻泡影| | 2018-7-6 14:35 | 显示全部楼层
本帖最后由 一路向北lm 于 2018-7-8 16:32 编辑
int main(void)
{
        int n;

        while(1)
        {
                if(scanf("%d", &n))
                {
                        printf("The value of n is: %d\n", &n);
                }
                else
                {
                        printf("excuse me!! please enter the correct number\n");
                }
        }
        return 0;
}

使用特权

评论回复
yanghelovehuang|  楼主 | 2018-7-6 15:54 | 显示全部楼层
梦幻泡影 发表于 2018-7-6 14:35
int main(void)
{
        int n;

你的代码一样会打印啊,输入字符串就和我的现象一样 循环打印

使用特权

评论回复
梦幻泡影| | 2018-7-6 16:54 | 显示全部楼层
yanghelovehuang 发表于 2018-7-6 15:54
你的代码一样会打印啊,输入字符串就和我的现象一样 循环打印

那就在else后面把n释放掉,我估计是存了一个值后没有释放地址,导致下次去读这个地址还会有数据

使用特权

评论回复
linqing171| | 2018-7-6 22:38 | 显示全部楼层
printf("The value of n is: %d\n", &n);   =》  printf("The value of n is: %d\n", n);

scanf %d 是读取一个整数,必须为  +或者减号或者数字开头。
如果读到不是数字的,则认为数字结束了。

比如上面的例子你输入  “3 4  5 6  a  7  8  9”  你会发现  空格回车之类的都可以做为终止符号,但是a不行。
更详细参考 ISO/IEC 9899:1999 (E) (俗称C99标准,所有的c语言编译器都要符合的国际标准)的 7.19.6.2 章节对sscanf(stdin 做了详细的说明。
比如:

第9段的 和格式%d不匹配的说明,以及其备注242:
242) fscanf pushes back at most one input character onto the input stream. Therefore, some sequences
that are acceptable to strtod, strtol, etc., are unacceptable to fscanf.
等效于把a再放回stdin里面。




第19断的例子3摘录如下:
19 EXAMPLE 3 To accept repeatedly from stdin a quantity, a unit of measure, and an item name:
#include <stdio.h>
/* ... */
int count; float quant; char units[21], item[21];
do {
count = fscanf(stdin, "%f%20s of %20s", &quant, units, item);
fscanf(stdin,"%*[^\n]");
} while (!feof(stdin) && !ferror(stdin));
20 If the stdin stream contains the following lines:
2 quarts of oil
-12.8degrees Celsius
lots of luck
10.0LBS of
dirt
100ergs of energy
the execution of the above example will be ana**us to the following assignments:
quant = 2; strcpy(units, "quarts"); strcpy(item, "oil");
count = 3;
quant = -12.8; strcpy(units, "degrees");
count = 2; // "C" fails to match "o"
count = 0; // "l" fails to match "%f"
quant = 10.0; strcpy(units, "LBS"); strcpy(item, "dirt");
count = 3;
count = 0; // "100e" fails to match "%f"
count = EOF;

使用特权

评论回复
linqing171| | 2018-7-6 22:41 | 显示全部楼层
scanf("%*[^\n]");
上面这句就是你所要的东西。

使用特权

评论回复
yanghelovehuang|  楼主 | 2018-7-9 09:57 | 显示全部楼层
梦幻泡影 发表于 2018-7-6 16:54
那就在else后面把n释放掉,我估计是存了一个值后没有释放地址,导致下次去读这个地址还会有数据 ...

这个也会打印, 我试过,只是不换行的循环打印

使用特权

评论回复
梦幻泡影| | 2018-7-9 10:40 | 显示全部楼层
yanghelovehuang 发表于 2018-7-9 09:57
这个也会打印, 我试过,只是不换行的循环打印

五楼的兄弟说的有道理,我只是在大一的时候用过几下scanf和printf函数,到现在都六七年不用了,电脑上也没装vc编译器,没有去验证,可能格式有点不对,现在都是在用MCU的程序,用不到这些函数,不过有一点就是,出错无非是逻辑没搞清楚或者是相关函数没理解到位导致的,我建议你还是花点时间细心去想想

使用特权

评论回复
yanghelovehuang|  楼主 | 2018-7-9 10:42 | 显示全部楼层
linqing171 发表于 2018-7-6 22:41
scanf("%*[^\n]");
上面这句就是你所要的东西。

谢谢啊 大神 用这句话算是解决了,但是这是什么意思呢?   我还有个问题就是,我就想输入一个数字,但是有人误操作输入了两个 如: 1 2,我该怎么判断出来并打印提示信息:请输入一个数字?

使用特权

评论回复
linqing171| | 2018-7-9 22:31 | 显示全部楼层
读一行自己再转换,比较麻烦,不如用库里面的scanf方便。
你按string的%s读入,然后再调用isdigital挨个判断,然后再atoi转换,... . .. 实在没有必要啊。库函数的方式就是在上世纪七八十年代总结出来最合理的方式。

使用特权

评论回复
yanghelovehuang|  楼主 | 2018-7-10 14:06 | 显示全部楼层
linqing171 发表于 2018-7-6 22:41
scanf("%*[^\n]");
上面这句就是你所要的东西。

大神还在吗 我想问下为什么我那样写输入字符会出现循环打印else里的内容呢?

使用特权

评论回复
linqing171| | 2018-7-10 22:18 | 显示全部楼层
yanghelovehuang 发表于 2018-7-10 14:06
大神还在吗 我想问下为什么我那样写输入字符会出现循环打印else里的内容呢? ...

第9段的 和格式%d不匹配的说明,以及其备注242:
242) fscanf pushes back at most one input character onto the input stream.

scanf把从stdin里面读出来的字符,看了一下不符合数字的特点,又放回了stdin。然后scanf函数返回了EOF。
然后你后面scanf还是%d,又取出来,又看了一下,又放回去,又返回EOF。
。。。。。。

使用特权

评论回复
yanghelovehuang|  楼主 | 2018-7-11 09:39 | 显示全部楼层
linqing171 发表于 2018-7-10 22:18
第9段的 和格式%d不匹配的说明,以及其备注242:
242) fscanf pushes back at most one input character  ...

大神 抱歉,还想问下,可是为什么我输入字符,打印scanf返回的信息是0啊?
n = scanf("%d ", &a);
printf("n = %d\n", n);
随便输入字符,n的返回值是0.

使用特权

评论回复
linqing171| | 2018-7-11 22:07 | 显示全部楼层
yanghelovehuang 发表于 2018-7-11 09:39
大神 抱歉,还想问下,可是为什么我输入字符,打印scanf返回的信息是0啊?
n = scanf("%d ", &a);
printf ...

0表示不是数字,EOF表示编码错误等。你输入汉字就会见到EOF了。
更详细的你看一下下面标准中的截图。
turbo c函数库大全等里面应该有介绍,中文版本的。 IDE的帮助里面应该也有。

scanf.png

使用特权

评论回复
53464634| | 2018-7-12 09:52 | 显示全部楼层
2018嵌入式高薪就业秘籍,c语言学习资料获取:加我QQ免费领取学习卡
      http://emb.hqyj.com/zhuanti/luxian/?lbx 学习路线
      http://emb.hqyj.com/courses/?lbx 课程
      http://emb.hqyj.com/VideoCourse/?lbx 视频教程
         QQ  3249798935     赶快联系我吧

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

156

主题

324

帖子

1

粉丝