几种输入方式是否读入\n的对比
事先声明:
仅适用于初学者,仅适用于初学者,仅适用于初学者。
里面一些内容实际上并不妥当甚至是错误的,只是为了便于刚开始学习时的理解,请大佬们轻喷。
这里仅仅列举和对比我已经知道的
先说一下缓冲区:
-
scanf()
scanf()函数结束读取时不会舍弃最后的回车符,但也不会读入。
也就是说回车符残留在缓冲区中。
即不仅仅是回车,空格和制表都是这样
强调一点:scanf()对所有的类都不支持,包括string类(编译对但输出错也有,反正我开了-wall能看见warning)
注意什么时候加不加取地址符号就行。 -
getchar()
只读取一个字符 -
gets()
可以接受一切字符,空格制表不停止,直到换行
但是会读入换行符
不推荐使用,因为容易缓冲区溢出 -
fgets(s,size,输入来源);
!!!实际上是错误的,自己创的里面的内容,与实际情况并不相符,只是为了便于自己理解!!!是为了解决gets()函数容易缓冲区溢出的问题而产生的
stream是流,一般来说是stdin即标准输入
遇到换行符表示输入结束
但是只读取限制字符个数,即size-1(需要安置末位的0),剩下的仍然在缓冲区中
会读入换行符!
当你用fgets读取时,由于一般我们会把数组设置的足够大,所以在与常量字符数组比较时一定一定要把结尾的换行符去掉
方法即用strlen(),即s[strlen(s)-1]=‘\0’实际上:
这是个文件函数,文件中读入一个字符串,但是由于OS会认为显示屏等标准输入输出也是文件,所以我们可以在输入来源里面写stdin,即标准输入,用来限制读取长度,更加安全。实际上输入来源这里面应该是一个文件,不过文件本来用的就少,用的时候注意一下就行。 -
cin
到这里已经与考试无关了
不过我还是记一记吧,因为这样也有好处
直接从缓冲区读数据,当缓冲区有残留数据时,会直接读入
自动分配类型,并且对string类型,只读到空格、换行、制表符就结束,停止读取
并且结束符不保存入变量之中,即仍残留在缓冲区
换言之,cin与scanf()非常相似,但是与fgets不同 -
cin.get(字符数组名,接收长度,结束符)
其中结束符意味着遇到该符号结束字符串读取,默认为换行符,即结束符为可选参数
即可以不写全,默认换行即读取一整行
注意不能用来读入string类型,可以用字符数组的方式读取
没有长度的话默认读取一个
即:ch=cin.get()==cin.get(char ch)
有人认为cin.get()存在的基本目的就是为了从c移植到c++的时候,直接用cin.get()来代替getchar()。
换句话说,cin.get()的返回值和其他cin.get()的成员函数返回cin对象不同,与getchar()相同,返回int。可以说cin.get()和getchar()没什么区别。
注意当一开始第一个字符即结束字符,将不会正常输出,但缓冲区中仍然有该结束符
不过注意cin.get()可以无限套娃,即cin.get().get() -
cin.getline(字符数组名,接收长度,结束符)
与cin.get()用法极为类似,但是有一点不同。当输入的字符串超长时,会引起cin函数的错误,后面的cin操作不再执行。
eg.void test_input() { char ch1,ch2[10]; cout<<"请输入字符串:"<<endl; cin.getline(ch2,6);//在不遇到结束符的情况下,最多可接收6-1=5个字符到ch2中 cin>>ch1; cout<<ch2<<endl; cout<<ch1<<"\n"<<(int)ch1<<endl; } /*输出为: zifuchuan zifuc -52 */
此处即大于最大长度5,导致cin函数错误,其既没有从缓冲区读入,也没有从键盘读入。
也就是说,用getline的话,最好确保数组足够大。
不过有一点需要*特别注意:
cin.get()每次读取一整行并把由回车键生成的换行符留在输入队列中,然而cin.getline()每次读取一整行并把由回车键生成的换行符抛弃。
这点尤其需要在用到常量字符数组的比较中注意,稍不留神就会出大问题。 -
getline(istream is,string str,结束符)
此处结束符仍然为可选参数。不过·······
其在string库下,而非前面的istream流。故所有调用前需要加上头文件#include<string>
(加个\不然显示不出来)
而且第二个参数为string类型,不再是char *
默认结束符为换行符,并且会舍弃最后一个换行符
但是前面是不是istream,一般用的时候就是getline(cin,s);
实际上专门有函数是用来清空缓冲区的,不过我现在的水平还达不到需要看这个东西的境界,故暂时略过。
这里还有个非常非常有意思的点
就是输入,是依靠队列实现的
但是输出,是依靠栈实现的
关于cin读整数跳过\n和空格
这里的缓冲区实际上是有个指针,这个指针会往后移,也就是说,你的\n或者空格还在缓冲区,指针还指向他,但是下次读的时候,发现不是就跳过了。这些东西仍然存在缓冲区中,这也就是为什么学长推荐我们用\n而不用endl,因为endl会清空缓冲区,你不知道什么时候突然就有可能出现一个难以排查的错误。