一:scanf

scanf一般可用于读取数字、字符、字符串; 

结论: 
(1)当 scanf 从缓冲区中读取单个字符(%c)时,若缓冲区中第一个字符是空格、tab或换行这些分隔符时,scanf 不会将其忽略,会读取并清除缓冲区的字符。 
(2)当 scanf 从缓冲区中读取数字或字符串(非单个字符)时,若缓冲区中第一个字符是空格、tab或换行这些分隔符时,scanf 会将其忽略(即不读取)并清除缓冲区的字符,继续读取下一个字符,若缓冲区为空,则继续等待。但是如果读取成功,字符后面的分隔符是残留在缓冲区的,scanf 不做处理。 
(3)scanf 读取字符串时,当遇到空格、回车和Tab键都会认为输入结束。当遇到回车,空格和tab键会自动在字符串后面添加’’,但是回车,空格和tab键仍会留在输入的缓冲区中。(所以它不能接收包含空格、回车或Tab等的字符串) 
(4)scanf() 读取字符串时, 
语法:scanf(“格式控制字符串”,变量地址列表); 
接受字符串时:scanf(“%s”,字符数组名或指针);

//第(1)点
#include <iostream> #include <cstdio> using namespace std; int main() { char ch; for(int i=0;i<3;i++) { scanf("%c",&ch); cout<<ch<<endl; } return 0; } 输入: a de 输出: a d
//第(2)点
#include <iostream> #include <cstdio> using namespace std; int main() { char ch[10]; for(int i=0;i<3;i++) { scanf("%s",&ch); cout<<ch<<endl; } return 0; } 输入: ssd xccxv cxcxv 输出: ssd xccxv cxcxv
//第(3)点
#include <iostream> #include <cstdio> using namespace std; int main() { char ch[10]; for(int i=0;i<3;i++) { scanf("%s",&ch); cout<<ch<<endl; } char sh[10]; cin.getline(sh,10); cout<<sh; return 0; } 输入: ahsbhj shbhdb sdhbj bsahd bmnb 输出: ahsbhj shbhdb sdhbj bsahd bm

二、gets 
gets 一般只用于读取字符串; 
结论: 
(1)gets可以接收空格,遇到回车认为输入结束; 
(2)gets 可接受回车键之前输入的所有字符,并用’n’替代 ‘’。回车键不会留在输入缓冲区中。 
(3)gets() 读取字符串时, 
语法:gets(字符数组名或指针); 
(4)gets(s) 函数中的变量s为一字符串指针。如果为单个字符指针,编译连接不会有错误,但运行后内存溢出错误。 
(5)gets函数可以无限读取,不会判断上限,以回车结束读取,所以应该确保buffer的空间足够大,以便在执行读操作时不发生溢出。

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
    char ch[100];
    gets(ch);
    cout<<ch<<endl;

    return 0;
}

输入:
        njdks njkn njnjkb       jkbh
输出:
        njdks njkn njnjkb       jkbh

三、getchar 
getchar()是在输入缓冲区顺序读入一个字符(包括空格、回车和Tab);注意,getchar函数只能接受单个字符,输入数字也按字符处理,输入多于一个字符时,只接收第一个字符。 
结论: 
(1)getchar 由宏实现:#define getchar() getc(stdin)。getchar有一个int型的返回值。当程序调用getchar时,程序就等着用户按键,用户输入的字符被存放在键盘缓冲区中,直到用户按回车为止,此时进入到输入缓冲区中(回车字符也放在缓冲区中)。 
(2)当用户键入回车之后,getchar才开始从stdin流中每次读入一个字符。getchar函数的返回值是用户输入的第一个字符的ASCII码,如出错返回-1,且将用户输入的字符回显到屏幕。 
(3)如果用户在按回车之前输入了不止一个字符,其他字符会保留在输入缓冲区中,等待后续getchar调用读取。即后续的getchar调用不会等待用户按键,而直接读取缓冲区中的字符,直到缓冲区中的字符读完为后,才等待用户按键。 
(4)使用getchar的场景: 
场景一: 
例如,前面的scanf()在读取输入时会在缓冲区中留下一个字符’n’,所以此时使用getchar()可以把这个回车符取走,从而保证读取正确。(从缓冲区读走一个字符,相当于清除缓冲区)

场景二:

while(getchar()!='n')

键盘输入的字符都存到缓冲区内,一旦键入回车,getchar就进入缓冲区读取字符,一次只返回第一个字符作为getchar函数的值,如果有循环或足够多的getchar语句,就会依次读出缓冲区内的所有字符直到’n’。如果需要消除 ‘n’ 的影响,可以用getchar();来清除,这里getchar();只是取得了’n’但是并没有赋给任何字符变量,所以不会有影响,相当于清除了这个字符。 
(6)可以用getche()或getch()代替getchar(),其作用是从键盘读入一个字符(不用按回车),注意要包含头文件<conio.h>

#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
    char ch;
    for(int i=0;i<4;i++)
    {
        ch=getchar();
        cout<<ch;
    }

    return 0;
}

输入:
asd
输出:
asd
//此处有空行

四、cin 
该操作符是根据后面变量的类型读取数据。 
输入结束条件 :遇到Enter、Space、Tab键。 
对结束符的处理 :不读取也不清除缓冲区中使得输入结束的结束符(Enter、Space、Tab) 
结论: 
当cin>>从缓冲区中读取数据(不论是字符、数字或字符串)时,若缓冲区中第一个字符是空格、tab或换行这些分隔符时,cin>>会将其忽略并清除,继续读取下一个字符,若缓冲区为空,则继续等待。但是如果读取成功,字符后面的分隔符是残留在缓冲区的,cin>>不做处理。

 sdfds//输入
sdfds
        bhjb bjb//输入
bhjb
bjb
//此处有空行
//此处有空行

五、cin.get( ) 
该函数有四种常用格式:无参,一参数,二参数 ,三参数
即cin.get(), cin.get(char ch), cin.get(array_name, Arsize) 
对应的函数原型如下: 
int cin.get(); //有啥读啥
istream& cin.get(char& var); //有啥读啥
istream& get ( char* s, streamsize n ); // 读取字符串时,默认以换行符结束。 
istream& get ( char* s, streamsize n, char delim ); // 读取字符串时,第三个参数可指定结束符。

#include <iostream>
#include <cstdio>
#include <cstdlib>

using namespace std;

int main()
{
    char ch;
        for(int i=0;i<5;i++)
        {
            ch=cin.get();
            cout<<ch;
        }
    return 0;
}
输入:
a12b
输出: a12b
//此处有空行

(2)读取字符串的情况: 
<1> cin.get(array_name, Arsize)是用来读取字符串的,可以接受空格字符,遇到Enter结束输入,按照长度(Arsize)读取字符。 
<2> 输入超长,则按需要的长度取数据。 

char ch, a[20]; 
cin.get(a, 5); 
输入: 
12345[Enter] 
输出: 
1234 

分析:输入超长,字符串按长度取了”1234”,而’5’仍残留在缓冲区中;注意:每个字符串的尾部都有一个空字符‘’,要考虑到长度内。 
<3> cin.get(array,20);读取一行时,遇到换行符时结束读取,但是不对换行符进行处理,换行符仍然残留在输入缓冲区。可以用cin.get()将换行符读入变量b来打印验证,发现打印结果为10,即换行符的ASCII码值。这也是cin.get()读取一行与使用getline读取一行的区别所在。getline读取一行字符时,默认遇到’n’时终止,并且将’n’直接从输入缓冲区中删除掉,不会影响下面的输入处理。 

char ch[10];
for(int i=0;i<3;i++)
{
  cin.
get(ch,10);
  cout
<<ch; } 输入: asd123cd[Enter] 输出: asd123cd//此时因换行符仍然残留在输入缓冲区并没被吸收而只读取了一次(第一次正常读取,后面读到的都时换行符'n',而此函数遇到换行符即结束读取)
char ch[10];
for(int i=0;i<3;i++)
{
  cin.get(ch,10);
  cin.get();//也可以直接写成cin.get(ch,10).get();   cout
<<ch<<endl; } 输入: asd123cd[Enter]
qwe[Enter]
cv[Enter] 输出: asd123cd
qwe
cv
//空行

<4> cin.get(str,size);读取一行时,只能将字符串读入C风格的字符串中,即char*;但是C++的getline函数可以将字符串读入C++风格的字符串中,即string类型。鉴于getline较cin.get()的这两种优点,建议使用getline进行行的读取。关于getline的用法,下文将进行详述。

六、cin.getline( ) 
函数作用:从标准输入设备键盘读取一串字符串,并以指定的结束符结束。 
函数原型有两个: 
istream& getline(char* s, streamsize count); // 默认以换行符结束 
istream& getline(char* s, streamsize count, char delim); 
结论: 
(1)cin.getline() 与 cin.get(array_name, Arsize)的读取方式差不多,以Enter结束,可以接受空格字符,按照长度(Arsize)读取字符。 
(2)cin.getline与cin.get的区别 
<1> cin.getline不会将结束符或者换行符残留在输入缓冲区中。 
<2> cin.get(array_name, Arsize)当输入的字符串超长时,不会引起cin函数的错误,后面的cin操作会继续执行,只是直接从缓冲区中取数据。但是cin.getline()当输入超长时,会引起cin函数的错误,后面的cin操作将不再执行。

char ch[10];
for(int i=0;i<3;i++)
{
  cin.getline(ch,10);
  cout<<ch<<endl;
}
输入:
123456789qwe
输出:
123456789
//
//
//三行空行

七、getline( ) 
C++中定义了一个在std名字空间的全局函数getline,因为这个getline函数的参数使用了string字符串,所以声明在了< string>头文件中了。 
getline利用cin可以从标准输入设备键盘读取一行,当遇到如下三种情况会结束读操作:1)到文件结束,2)遇到函数的定界符,3)输入达到最大限度。 
函数原型有两个重载形式: 
istream& getline ( istream& is, string& str); / /默认以换行符结束 
istream& getline ( istream& is, string& str, char delim); 

string str;
 for(int i=0;i<2;i++)
{
    getline(cin,str);
    cout<<str<<endl;
}
输入:
asd145cd
zxc47rtjk
输出:
asd145cd
zxc47rtjk
//空行

结论: 
(1)注意,getline遇到结束符时,会将结束符一并读入指定的string中,再将结束符替换为空字符(’’)。因此,进行从键盘读取一行字符时,建议使用getline,较为安全。 
(2)和 cin.getline()类似,但是cin.getline()属于istream流,而getline()属于string流,是不一样的两个函数。

内容来源于网络如有侵权请私信删除
你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!

相关课程