参考博客1
参考博客2
一、scanf()
#include<stdio.h>
scanf()函数遇以下情况结束一个数据的输入:① 遇空格、“回车”、“跳格”键。② 遇宽度结束。③ 遇非法输入。在缓冲区读数据,缓冲区空了才要求再次输入。
scanf()读字符时,会把空格、回车正常读入,因为它们有ASCII码
scanf()读非字符时,把空格、回车、Tab作为分隔符,读数据时忽略开始的分隔符,并遇到下一个分隔符结束,并且分隔符会被留在缓冲区,下一次读数据时需要注意,即如果下次是读字符,则要先清除缓冲区残留,如果下次读非字符,也把残留的空格、回车、Tab作为分隔符忽略,则可以不考虑:
1、输入aaa回车bbb回车ccc回车,则每次输入的回车都被字符c读入并输出10,最后给getchar()输入d,说明遇分隔符结束输入,并且分隔符被保留缓冲区
2、输入aaa bbb ccc 回车,则每个字符串后面的空格作为分隔符留在缓冲区,被字符c读入,最后的回车被getchar()读入
1、输入aaa回车bbb回车ccc回车,只有最后一个回车被getchar()读入,其余的在循环读入字符串时忽略
2、输入aaa bbb ccc回车,每次读字符串时,前面残留的空格被忽略,最后的回车被getchar()读入
3、输入aaa bbb ccc 回车,ccc后面的空格被getchar()读入,最后的回车残留在缓冲区
其他例子:
#include "stdafx.h"
#include <stdio.h>
int main(){
char str[80];
int a,b;
scanf("%s",&str);
scanf("%d",&a);
scanf("%d",&b);
return 0;
}
若输入”fhdsia 12 34”,12前、34前有很多空格,程序直接运行结束,中途不再提示输入。str对”fhdsia”,a对12,b对34
若输入”fhdsia 12 “,这样系统还会提示你再输入一次数据,对应语句为scanf("%d",&b);
#include "stdafx.h"
#include <stdio.h>
int main()
{
char str[80];
char a,b;
scanf("%s",&str);
scanf("%c",&a);
scanf("%c",&b);
return 0;
}
若输入”afdsf ”然后回车,注意afsdf后面空格大于2个,则由于char会把标准输入区的空格或回车当做输入值,故输入”afdsf ”(2个或2个以上的空格)后,程序直接运行结束,a对应标准输入区中的空格,同理b也对应空格。
若输入”afdsf”后直接回车,这样,str对应afdsf,a对应回车,这样还会提示继续输入数据用来对应b。
注意的是:只有字符char在输入流中的获取会承认空格或回车中的换行符为所要取的值,别的如字符串或int类型均不认为空格或回车中的换行符为其值。即"%c"格式能读空格、换行符
二、gets()
#include<stdio.h>
原型:char *gets( char *buffer );
功能:回车换行符结束。从stdin流中读取字符串,直至接受到换行符或EOF时停止,并将读取的结果存放在buffer指针所指向的字符数组中。换行符不作为读取串的内容,读取的换行符被转换为'\0',并由此来结束字符串。读入时不需要考虑换行符即回车键不会留在输入缓冲区中。
返回值:读入成功,返回与参数buffer相同的指针;读入过程中遇到EOF(End-of-File)或发生错误,返回NULL指针。所以在遇到返回值为NULL的情况,要用ferror或feof函数检查是发生错误还是遇到EOF。
注意:
本函数可以无限读取,不会判断上限,所以程序员应该确保buffer的空间足够大,以便在执行读操作时不发生溢出。如果溢出,多出来的字符将被写入到堆栈中,这就覆盖了堆栈原先的内容,破坏一个或多个不相关变量的值,为了避免这种情况,我们可以用gets_s()来替换gets()。这个事实导致gets函数只适用于玩具程序。
gets(s)函数与scanf("%s:",&s)相似,但不完全相同,使用scanf("%s",&s);函数输入字符串时存在一个问题,就是如果输入了空格会认为字符串结束,空格后的字符将作为下一个输入项处理,但gets()函数将接收输入的整个字符串直到遇到换行为止。
gets(s);函数中的变量s为一字符串。如果为单个字符,编译连接不会有错误,但运行后会出现”Null pointer asignment"的错误。
三、cin
#include <iostream.h>
cin代表标准输入设备,使用提取运算符 ">>" 从设备键盘取得数据,送到输入流对象cin中,然后送到内存。使用cin可以获得多个从键盘的输入值,其具体使用格式:cin >> 表达式1 >>表达式2 ... >> 表达式n;
------cin输入会根据空格、回车、以及要输入的数据类型进行对应数据分配。但你若某一个输入的数据不对应,则下面的要输入的就会分配给错误的信息,不会再提示你输入数据。
如下:
#include "stdafx.h"
#include<iostream.h>
int main()
{
int i,j;
char s;
cin>>i;
cout<<i<<endl;
cin>>j;
cout<<j<<endl;
cin>>s;
cout<<s<<endl;
return 0;
}
--该程序就是让先输入两个int,再输入一个人char,你可以一个一个输入,也可以一起输入,比如输入 12 22 a。也可以先输入 12 22,会再提示输入s对应的值,但如果你输入先输入 a或a 12 b或 a 12等只要有一个不对应,则从那个不对应的开始,数据均错,直接回车,导致程序直接运行结束,不会再提示你输入j的值,s的值。
十一、getline()
getline(cin,str); getline(cin,str,'x');
string类对象的成员函数,使用时需头文件#include <string>,注意不是cstring
原型:istream& getline ( istream& is, string& str, char delim );
istream& getline ( istream& is, string& str );
参数:is 进行读入操作的输入流;str 存储读入的内容;delim 终结符
功能:将输入流is中读到的字符存入str中,直到遇到终结符delim才结束。对于第一个函数delim是可以由用户自己定义的终结符;对于第二个函数delim默认为 '\n'(换行符)。
函数在输入流is中遇到文件结束符(EOF)或者在读入字符的过程中遇到错误都会结束。
在遇到终结符delim后,delim会被丢弃,不存入str中。在下次读入操作时,将在delim的下个字符开始读入。
十、cin.getline()
cin.getline(字符指针,字符个数N,结束符);
istream类的成员函数
功能是:一次读取多个字符(包括空白字符),直到读满 N-1 个,或者遇到指定的结束符为止(默认的是以'\n'结束)。
#include<iostream>
#include <string>
using namespace std;
int main(){
char a[6];
cin.getline(a,6);
cout<<a<<endl;
return 0;
}
比如输入:abc回车,则a为”abc”,因为cin.getline()以回车符为结束标志,读取N-1个字符。
对于char a[6];cin.getline(a,N);中的N最大为7。如果大于7,对于a[6]来说没有意义,因为a[6]数组到元素a[5]有意义,a[6]就没有意义(从0开始的)。cin.getline(a,5,'a');则a数组最多取输入的前5个字符,但遇到字符’a’结束,且遇到字符’a’结束优先取最多5个字符。
cin.getline();一次输入对应一条该语句,若cin.getline(a,5)即使你在控制台输入再多,也之最多取前4个字符。以回车换行符为结束标志。
但是,对于下面类似的:
#include<iostream>
#include <string>
using namespace std;
int main(){
char a[6];
cin.getline(a,6);
cout<<a<<endl;
cin.getline(a,6);
cout<<a<<endl;
return 0;
}
如果输入为:abcdef(反正只要大于5(包括空格),第一个a会取前5个字符,但第二个则为空)
#include "stdafx.h"
#include<iostream>
#include <string>
#include <stdlib.h>
using namespace std;
int main(){
char a[4];
char b[4];
cin.getline(a,5);
cin.clear(); //更正输入
cout<<a<<endl;
cin.getline(b,5);
cout<<b<<endl;
return 0;
}
若输入abcdegfgaa,则前四个字符abcd为a,egfg对应b;
若输入ab egfgaa,则前四个字符ab e为a,egfg对应b;
----也就是当第一个输入不满足小于cin.getline(,N,)中N个字符,则cin.clear();起到一次校正作用,只一次。
如:
#include "stdafx.h"
#include<iostream>
#include <string>
#include <stdlib.h>
using namespace std;
int main(){
char a[4];
char b[4];
cin.getline(a,5);
cin.clear(); //更正输入
cout<<a<<endl;
cin.getline(b,5);
cout<<b<<endl;
cin.getline(b,5);
cout<<b<<endl;
return 0;
}
若输入:abcdqqqqww,大于8,则第三个cin.getline()则为空格。
九、cin.get()
有点类似于getchar(),针对字符,会把空格空格(十进制对应32)、回车中的换行符(十进制对应10)当做正常值。
#include "stdafx.h"
#include<iostream>
#include <string>
using namespace std;
int main(){
int i,j;
char s;
i=cin.get();
cout<<i<<endl;
j=cin.get();
cout<<j<<endl;
int str;
str=cin.get();
cout<<str<<endl;
return 0;
}
如果输入1回车,则输出为:
49
10
等待str的输入。
如果输入1 回车,(1后面有一个空格),则输出为:
49
32
10
如果输入1 回车,(1后面有二个空格),则输出为:
49
32
32
七、ungetc()
把一个字符退回到输入流中
用 法:int ungetc(char c, FILE *stream);
#include "stdafx.h"
#include <stdio.h>
#include <ctype.h>
int main(){
int ch;
printf( "Enter an integer: " );
ch = getchar() ;
printf("%d\n",ch);
ungetc( ch, stdin );
int s;
s=getchar();
printf("%d\n",s);
return 0;
}
输入12,则会运行结束,不再要求输入数据,输出为49(换行)49