关于scanf和cin的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于scanf和cin的问题相关的知识,希望对你有一定的参考价值。

写了个简单的代码,如下
int main()

int i = -1;

while (scanf("%d", &i) != EOF && i == -1)

printf("%d\n", i);


return 0;

运行时,我输入字符'a',程序死循环了?这是为什么呢?它不会把'a'当成97赋值给i吗?
使用cin>>i,也有这个问题。求答人解答

输入字符‘a'.输入错误输入,一旦输入了错误的类型,你的程序不是死锁,就是得到一个错误的结果。
解决方法:scanf()函数执行成功时的返回值是成功读取的变量数,也就是说,你这个scanf()函数有几个变量,如果scanf()函数全部正常读取,它就返回几。
所以你的函数为了避免输入错误,应该改为
#include <stdio.h>
int main()

int i = -1;

while (scanf("%d", &i) == 1 && i == -1)

printf("%d\n", i);


return 0;
参考技术A 首先我我指出改正的方法吧
while (scanf("%d", &i) != EOF && i == -1)
改成
while (scanf("%d", &i) && i == -1)
关于你的问题
首先scanf函数的原型是int scanf(const char * _Format,...)函数的第一个参数是格式控制符,后面的输入的参数列表,当输入的参数不满足前面的格式控制时候,返回值0;就比如说你程序里面的输入a,就是字符‘a’,但是他要求是一个整数,所以返回0,
然后在头文件<stdio.h>中我们发现这样一条预处理#define EOF (-1)也就是说,eof实际上就是-1,
这个时候当然满足了0!=-1,和i==-1的了哟,但是由于scanf函数错误,所以就无限循环了
至于cin流输入,基本是一个道理,不过他是流的状态出错(这里好像是,有点忘,基本没有用过)
以上是个人理解,欢迎一起交流,同时欢迎你光临我的空间

对于scanf和cin的输入输出速度的验证

本文为https://www.byvoid.com/zhs/blog/fast-readfile的验证性文章

---------------------------------------------------------------------------

首先生成一千万个随机数

 1 #include<cstdio>                       
 2 #include<ctime>                        
 3 #include<cstdlib>                      
 4 int main ()                            
 5 {                                      
 6         freopen("data.txt","w",stdout);
 7         srand(time(0));                
 8         for(int i=0;i<10000000;i++)     
 9                 printf("%d ",rand());  
10         return 0;                      
11 }

我用重定向把数据导出到"data.txt"了。

然后,用scanf来读取数据,并计时

 1 #include<cstdio>                                               
 2 #include<ctime>
 3 int a[10000000];                                                
 4 int main ()                                                    
 5 {                                                              
 6         int start = clock();                                 
 7         freopen("data.txt","r",stdin);                         
 8         for(int i=0;i<10000000;i++)                             
 9                 scanf("%d",&a[i]);                                
10         printf("%.3lf\n",double(clock()-start)/CLOCKS_PER_SEC);
11 }

执行之后,使用时间为1.18s,相比于原文的2.01秒,缩短了一截,然后测试一下使用cin输入的情况,代码如下:

 1 #include<cstdio>
 2 #include<ctime>
 3 #include<iostream>
 4 int a[10000000];
 5 int main ()
 6 {
 7         int start = clock();
 8         freopen("data.txt","r",stdin);
 9         for(int i=0;i<10000000;i++)
10                 std::cin>>a[i];
11         printf("%.3lf\n",double(clock()-start)/CLOCKS_PER_SEC);
12 }

cin的使用时间为4.67s,比scanf更长,但是相比于原文的6.38s还是短得多。
然后取消cinstdin之间的同步之后,代码如下:

 1 #include<cstdio>
 2 #include<ctime>
 3 #include<iostream>
 4 int a[10000000];
 5 int main ()
 6 {
 7         int start = clock();
 8         std::ios::sync_with_stdio(false);
 9         freopen("data.txt","r",stdin);
10         for(int i=0;i<1000000;i++)
11                 std::cin>>a[i];
12         printf("%.3lf\n",double(clock()-start)/CLOCKS_PER_SEC);
13 }

时间大幅缩短,为1.24s,与scanf很接近了。
然后按原文测试读入整个文件,代码如下:

 1 #include<iostream>                                              
 2 #include<ctime>                                                 
 3 #include<cstdio>                                                
 4 const int MAXN = 10000000;                                      
 5 const int MAXS = 60*1024*1024;                                  
 6 int numbers[MAXN];                                              
 7 char buf[MAXS];                                                 
 8                                                                 
 9 void analyse(char *buf, int len =MAXS)                          
10 {                                                               
11         int i;                                                  
12         numbers[i=0]=0;                                         
13         for(char *p=buf;*p && p-buf<len;p++)                    
14         if(*p ==  )                                           
15                 numbers[++i]=0;                                 
16         else                                                    
17                 numbers[i]=numbers[i]*10+*p-0;                
18 }                                                               
19                                                                 
20 void fread_analyse()                                            
21 {                                                               
22         freopen("data.txt","rb",stdin);                         
23         int len = fread(buf,1,MAXS,stdin);                      
24         buf[len]=\0;                                          
25         analyse(buf,len);                                       
26 }                                                               
27                                                                 
28 int main ()                                                     
29 {                                                               
30         int start = clock();                                    
31         fread_analyse();                                        
32         printf("%.3lf\n",double(clock()-start)/CLOCKS_PER_SEC); 
33         return 0;                                               
34 }

时间如原文一般,大幅缩短,我这里测试得到0.37s,使用read测试,代码如下:

#include<iostream>                                             
#include<ctime>                                                
#include<cstdio>                                               
#include<unistd.h>                                             
#include<fcntl.h>                                              
const int MAXN = 10000000;                                     
const int MAXS = 60*1024*1024;                                 
int numbers[MAXN];                                             
char buf[MAXS];                                                
                                                               
void analyse(char *buf, int len =MAXS)                         
{                                                              
        int i;                                                 
        numbers[i=0]=0;                                        
        for(char *p=buf;*p && p-buf<len;p++)                   
        if(*p ==  )                                          
                numbers[++i]=0;                                
        else                                                   
                numbers[i]=numbers[i]*10+*p-0;               
}                                                              
                                                               
void read_analyse()                                            
{                                                              
        int fd = open("data.txt",O_RDONLY);                    
        int len = read(fd,buf,MAXS);                           
        buf[len]=\0;                                         
        analyse(buf,len);                                      
}                                                              
                                                               
int main ()                                                    
{                                                              
        int start = clock();                                   
        read_analyse();                                        
        printf("%.3lf\n",double(clock()-start)/CLOCKS_PER_SEC);
        return 0;                                              
}

测试时间为0.31s,有所进步,不过不是非常明显。
调用mmap,代码如下:

 1 #include<iostream>                                                      
 2 #include<ctime>                                                         
 3 #include<cstdio>                                                        
 4 #include<unistd.h>                                                      
 5 #include<fcntl.h>                                                       
 6 #include<sys/mman.h>                                                    
 7 const int MAXN = 10000000;                                              
 8 const int MAXS = 60*1024*1024;                                          
 9 int numbers[MAXN];                                                      
10 char buf[MAXS];                                                         
11                                                                         
12 void analyse(char *buf, int len =MAXS)                                  
13 {                                                                       
14         int i;                                                          
15         numbers[i=0]=0;                                                 
16         for(char *p=buf;*p && p-buf<len;p++)                            
17         if(*p ==  )                                                   
18                 numbers[++i]=0;                                         
19         else                                                            
20                 numbers[i]=numbers[i]*10+*p-0;                        
21 }                                                                       
22                                                                         
23 void mmap_analyse()                                                     
24 {                                                                       
25         int fd = open("data.txt",O_RDONLY);                             
26         int len = lseek(fd,0,SEEK_END);                                 
27         char *mbuf = (char *) mmap(NULL,len,PROT_READ,MAP_PRIVATE,fd,0);
28         analyse(mbuf,len);                                              
29 }                                                                       
30                                                                         
31 int main ()                                                             
32 {                                                                       
33         int start = clock();                                            
34         mmap_analyse();                                                 
35         printf("%.3lf\n",double(clock()-start)/CLOCKS_PER_SEC);         
36         return 0;                                                       
37 }

达到0.49s,与原文不符(原文中使用mmnp耗时更短,在我的测试中,耗时变长了),可能是代码与原作者的不一样,原作者只给出一部分代码,而测试需要写出完整的代码,可能我写的代码有问题。
以上测试结果在腾讯云上进行,因为原作者当时的硬件条件可能比不上我所使用的环境,我在树莓派 3B和我自己的电脑上测试了一下,所有平台硬件信息如下:

硬件信息对比
平台/硬件和软件信息 Cent OS Raspberry Windows
CPU 1 Core Broadcom BCM2837 1.2GHz intel Core 5200u 2.2GHz
RAM 1GB 1GB 12GB
Gcc 4.8.5 4.9.2 5.3.0

PS: 这里忽略了硬盘的性能,理论上来说,硬盘的性能肯定能影响读写速度,只是没有较好的方法比较三个平台的硬盘性能,只能作罢。不过在下面的表中我对比了我自己电脑上在Windows环境下和Linux环境下的情况。相较于原文,舍去VS的比较信息,全部使用了GNU/GCC.

测试结果如下

方法/平台/耗时(s) Cent OS Raspberry Windows(本机) Ubuntu(本机)
scanf 1.180 14.786 4.488 1.158
cin 13.026 61.255 13.026 4.309
cin(取消同步) 1.240 7.694 8086 1.135
fread 0.37 3.503 0.327 0.284
read 0.31 2.975 0.370 0.285
mmap 0.49 5.945 NULL 0.447

在同等硬件条件下,Windows比Linux慢得多,在同等环境下,硬件好的自然快,树莓派充分证明了这一点。

以上是关于关于scanf和cin的问题的主要内容,如果未能解决你的问题,请参考以下文章

关于scanf与cin哪个快的问题

关于scanf 与 cin gets(),getline()......输入输出字符串的区别

关于编程比赛中输入输出的问题

c++接收问题为何cin能接收,scanf接收就出错?

关于std::ios::sync_with_stdio(false)

cin 字符串输入