c++中cincout与scanfprintf的区别⽐较
cin 、cout   
基本说明:
  cin代表标准输⼊设备,使⽤提取运算符 ">>" 从设备键盘取得数据,送到输⼊流对象cin中,然后送到内存。
  cin是输⼊流,cout是输出流,重载了">>"、"<<"运算符,包含在头⽂件<iostream>中。
  先把要输出的东西存⼊缓冲区,再输出,导致效率降低,cin是⾃动判断你的变量类型,⽐如⼀个char数据只能⽤默认的char⽅法取数据。
scanf 、printf
基本说明:
  scanf是格式化输⼊,printf是格式化输出,包含在头⽂件<stdio.h>中。
  因为scanf是⽤指针操作的,没有类型安全机制,⽐如⼀个char类型数据你就可以⽤%f获得输⼊,⽽不会
报错,但在运⾏时会出现异常。
  scanf()函数取数据是遇到回车、空格、TAB就会停⽌,如例1,第⼀个scanf()会取出"Hello",⽽"world!"还在缓冲区中,这样第⼆个scanf会直接取出这些数据,⽽不会等待从终端输⼊。
例1:
#include <stdio.h>
int main()
{
  char str1[20], str2[20];
  scanf("%s",str1);
  printf("%s\n",str1);
  scanf("%s",str2);
  printf("%s\n",str2);
  return 0;
}
测试⼀输⼊:
Hello world!
输出:
Hello
world!
第⼀个scanf()会取出"Hello",⽽"world!"还在缓冲区中,这样第⼆个scanf会直接取出这些数据,⽽不会等待从终端输⼊。
为了避免出现上述问题,必须要清空缓冲区的残留数据,可以⽤以下的⽅法解决:
⽅法1:C语⾔⾥提供了函数清空缓冲区,只要在读数据之前先清空缓冲区就没问题了!
这个函数是fflush(stdin)。
⽅法2:⾃⼰取出缓冲区⾥的残留数据。
函数printf(说实话这个语句我也没看懂,呵呵!为什么格式控制是这样的!希望⾼⼿指点⼀下!)
scanf("%[^\n]",string);
gets()
基本说明:
  gets()函数⽤来从标准输⼊设备(键盘)读取字符串直到换⾏符结束,但换⾏符会被丢弃,然后在末尾添加'\0'字符。包含在头⽂件<stdio.h>中。
  gets(s)函数与 scanf("%s",&s) 相似,但不完全相同,使⽤scanf("%s",&s) 函数输⼊字符串时存在⼀个问题,就是如果输⼊了空格会认为字符串结束,空格后的字符将作为下⼀个输⼊项处理,但gets()函数将接收输⼊的整个字符串直到遇到换⾏为⽌。
原型:
  char*gets(char*buffer);
例2:
#include <stdio.h>
int main()
{
  char str1[20], str2[20];
  gets(str1);
  printf("%s\n",str1);
  gets(str2);
  printf("%s\n",str2);
  return 0;
}
测试:
Hello world! [输⼊]
Hello world! [输出]
12345 [输⼊]
12345 [输出]
为了避免出现上述问题,必须要清空缓冲区的残留数据,可以⽤以下的⽅法解决:⽅法1:C语⾔⾥提供了函数清空缓冲区,只要在读数据之前先清空缓冲区就没问题了!这个函数是fflush(stdin)。⽅法2:⾃⼰取出缓冲区⾥的残留数据。(说实话这个语句我也没看懂,呵呵!为什么格式控制是这样的!希望⾼⼿指点⼀下!) scanf("%[^\n]",string);
输⼊操作的原理
与前⼀节中提到的scanf函数⼀样,程序的输⼊都建有⼀个缓冲区,即输⼊缓冲区。⼀次输⼊过程是这样的,当⼀次键盘输⼊结束时会将输⼊的数据存⼊输⼊缓冲区,⽽cin函数直接从输⼊缓冲区中取数据。正因为cin函数是直接从缓冲区取数据的,所以有时候当缓冲区中有残留数据时,cin函数会直接取得这些残留数据⽽不会请求键盘输⼊,这就是例⼦中为什么会出现输⼊语句失效的原因!
cin的⼀些输⼊函数和操作符
cin is a extern istream object。提供了很多可⽤的成员函数和重载的操作符,如:cin<<, (),  line()等。下⾯我们来了解⼀下这⼏个函数:
⼀. cin<<
该操作符是根据后⾯变量的类型读取数据。
输⼊结束条件:遇到Enter、Space、Tab键。
对结束符的处理:丢弃缓冲区中使得输⼊结束的结束符(Enter、Space、Tab)
⼆.()
该函数有三种格式:⽆参,⼀参数,⼆参数
即(), (char ch), (array_name,  Arsize)
读取字符的情况:
输⼊结束条件:Enter键
对结束符处理:不丢弃缓冲区中的Enter
<() 与 (char ch)⽤于读取字符,他们的使⽤是相似的,
即:() 与 (ch)是等价的。
读取字符串的情况:
<(array_name, Arsize)是⽤来读取字符串的,可以接受空格字符,遇到Enter结束输⼊,按照长度(Arsize)读取字符, 会丢弃最后的Enter字符。
程序6:
#include <iostream>
using namespace std;
int main ()
{
char a[20];
<(a, 10);
cout<<a<<endl;
return 0;
}
测试⼀输⼊:
abc def[Enter]
输出:
abc def
【分析】说明该函数输⼊字符串时可以接受空格。
测试⼆输⼊:
1234567890[Enter]
输出:
123456789
【分析】输⼊超长,则按需要的长度取数据。
程序7:
#include <iostream>
using namespace std;
int main ()
{
char ch, a[20];
<(a, 5);
cin>>ch;
cout<<a<<endl;
cout<<(int)ch<<endl;
return 0;
}
测试⼀输⼊:
12345[Enter]
输出:
1234
53
【分析】第⼀次输⼊超长,字符串按长度取了"1234",⽽'5'仍残留在缓冲区中,所以第⼆次输⼊字符没有从键盘读⼊,⽽是直接取了'5',所以打印的ASCII值是53('5'的ASCII值)。
测试⼆输⼊:
1234[Enter]
a[Enter]
输出:
1234
97
【分析】第⼆次输⼊有效,说明该函数把第⼀次输⼊后的Enter丢弃了!
三.line()
但是这两个函数是有区别的:
<(array_name,  Arsize)当输⼊的字符串超长时,不会引起cin函数的错误,后⾯的cin操作会继续执⾏,只是直接从缓冲区中取数据。但是line()当输⼊超长时,会引起cin函数的错误,后⾯的cin操
作将不再执⾏。(具体原因将在下⼀部分"cin的错误处理"中详细介绍)
程序8:
#include <iostream>
using namespace std;
int main ()
{
char ch, a[20];
cin>>ch;
cout<<a<<endl;
cout<<(int)ch<<endl;
return 0;
}
测试输⼊:
12345[Enter]
输出:
1234
-52
【分析】与(array_name, Arsize)的例程⽐较会发现,这⾥的ch并没有读取缓冲区中的5,⽽是返回了-52,这⾥其实cin>>ch语句没有执⾏,是因为cin出错了!