几种输入方式是否读入\n的对比

几种输入方式是否读入\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会清空缓冲区,你不知道什么时候突然就有可能出现一个难以排查的错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值