鱼C论坛

 找回密码
 立即注册
查看: 1757|回复: 0

[技术交流] C++(3rd):cin.get与cin.getline

[复制链接]
发表于 2021-1-31 14:50:15 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 一叶枫残 于 2021-2-8 18:00 编辑

cin.get与cin.getline

对于这个函数
一.当作用于单个字符的变量时,它只会读取一个字符,例如
  1. #include <iostream>

  2. using namespace std;

  3. int main()
  4. {
  5.         char a;
  6.        
  7.         a = cin.get();
  8.        
  9.         cout << a << endl;
  10.          
  11.         return 0;
  12. }
复制代码

下面是各种输入情况:
(1)输入一个字符,例如数字,字母,或者符号(英文输入状态下)
这个字符就会赋值给a,cout可以正常输入;
(2)输入多个字符,
只会取输入的第一个字符赋值给a,cout无法把输入的多个字符输出,只能输出赋值的第一个字符;
(3)输入中文或者中文下的标点符号
cout无输出;

对于(3)的情况,经过调试后发现,当输入不同中文和不同的中文符号时,a的ascii码值由初始的0变为负数,这个情况和c语言下时一样的,对于中文的字符和标点符号只能用字符串来储存;

对于这个程序,a = cin.get()还可以改为
  1. cin.get(a)
复制代码

作用是相同的

二.当作用于字符串时
  1. #include <iostream>

  2. using namespace std;

  3. int main()
  4. {
  5.         char a[15];
  6.        
  7.                 cout << "请输入内容:" << endl;
  8.                 cin.get(a,10);
  9.                
  10.                 cout << "a:" << a << endl;
  11.         return 0;
  12. }
复制代码

注意:这里的cin.get(a,10)不能写成a = cin.get() 或者 cin.get(a),否则编译器会报错

不同情况的输入对应的输出
情况1:
  1. 请输入内容:
  2. 0123456
  3. a:0123456
复制代码
  1. 请输入内容:
  2. 0123456789abcd
  3. a:012345678
复制代码


情况2:
  1. 请输入内容:

  2. a:
复制代码


把cin.get(a,10)改为cin.get(a,20),此时的允许写入的长度已经超过原来的20:
情况3:
  1. 请输入内容:
  2. 0123456789abcdefghijklmn
  3. a:0123456789abcdefghi
复制代码


对于情况3,我们用以下代码来探究下a的空间大小是否发生了变化
  1. #include <iostream>

  2. using namespace std;

  3. int main()
  4. {
  5.         char a[15];
  6.        
  7.         cout << "未运行时,a所占内存空间大小:" << sizeof(a) << endl;

  8.         cout << "请输入内容:" << endl;
  9.         cin.get(a,20);
  10.         cout << "a:" << a << endl;
  11.        
  12.         cout << "运行后,a所占内存空间大小:" << sizeof(a) << endl;
  13.          
  14.         return 0;
  15. }
复制代码

情况1:当输入的长度小于字符串定义的长度时
  1. 未运行时,a所占内存空间大小:15
  2. 请输入内容:
  3. 0123456789a
  4. a:0123456789a
  5. 运行后,a所占内存空间大小:15
复制代码


情况2:当输入的长度大于字符串定义的长度而小于cin.get允许进入的长度时
  1. 未运行时,a所占内存空间大小:15
  2. 请输入内容:
  3. 0123456789abcdefgh
  4. a:0123456789abcdefgh
  5. 运行后,a所占内存空间大小:15
复制代码


情况3:当输入的长度大于cin.get允许进入的长度时
  1. 未运行时,a所占内存空间大小:15
  2. 请输入内容:
  3. 0123456789abcdefghigklmn
  4. a:0123456789abcdefghi
  5. 运行后,a所占内存空间大小:15
复制代码


我们发现,a所占的内存大小无论哪种情况都没用发生改变
那么我们上述代码的基础上在后面加上
  1.         int i;
  2.         for(i = 0; i<20 ;i++)
  3.         {
  4.                 cout << i << ":"<< a[i] << endl;
  5.         }
复制代码

输入运行后结果为
  1. 未运行时,a所占内存空间大小:15
  2. 请输入内容:
  3. 0123456789abcdefghijklmn
  4. a:0123456789abcdefghi
  5. 运行后,a所占内存空间大小:15
  6. 0:0
  7. 1:1
  8. 2:2
  9. 3:3
  10. 4:4
  11. 5:5
  12. 6:6
  13. 7:7
  14. 8:8
  15. 9:9
  16. 10:a
  17. 11:b
  18. 12:c
  19. 13:d
  20. 14:e
  21. 15:f
  22. 16:g
  23. 17:h
  24. 18:i
  25. 19:
复制代码


我们发现a居然储存了超过自己定义长度的字符串,为进一步探究,我们把每一个位置的地址也输出一遍,即把cout << i << ":"<< a[i] << endl改为
  1. cout << i << ":"<< a[i];
  2. cout << "  地址为:" << (void *)& a[i] << endl;
复制代码

结果为
  1. 未运行时,a所占内存空间大小:15
  2. 请输入内容:
  3. 0123456789abcdefghijklmn
  4. a:0123456789abcdefghi
  5. 运行后,a所占内存空间大小:15
  6. 0:0  地址为:0x70fdf0
  7. 1:1  地址为:0x70fdf1
  8. 2:2  地址为:0x70fdf2
  9. 3:3  地址为:0x70fdf3
  10. 4:4  地址为:0x70fdf4
  11. 5:5  地址为:0x70fdf5
  12. 6:6  地址为:0x70fdf6
  13. 7:7  地址为:0x70fdf7
  14. 8:8  地址为:0x70fdf8
  15. 9:9  地址为:0x70fdf9
  16. 10:a  地址为:0x70fdfa
  17. 11:b  地址为:0x70fdfb
  18. 12:c  地址为:0x70fdfc
  19. 13:d  地址为:0x70fdfd
  20. 14:e  地址为:0x70fdfe
  21. 15:f  地址为:0x70fdff
  22. 16:g  地址为:0x70fe00
  23. 17:h  地址为:0x70fe01
  24. 18:i  地址为:0x70fe02
  25. 19:   地址为:0x70fe03
复制代码

可以看出地址时连续的,cin.get的作用也一目了然了。

与cin.get用法相同的是cin.getline,如下
  1. #include <iostream>

  2. using namespace std;

  3. int main()
  4. {
  5.         char a[10];

  6.         cout << "请输入内容:" << endl;
  7.         cin.getline(a,10);

  8.         cout << "a:" << a << endl;
  9.        
  10.         return 0;
  11. }
复制代码
  1. 请输入内容:
  2. 0123456789
  3. a:012345678
复制代码


与cin.get不同的是,cin.get会把换行符留在缓冲区,导致下一个输入失败,例如
对于cin.get
  1. #include <iostream>

  2. using namespace std;

  3. int main()
  4. {
  5.         char a[10],b[10];

  6.         cout << "请输入内容:" << endl;
  7.         cin.get(a,10);
  8.         cin.get(b,10);
  9.        
  10.         cout << "a:" << a << endl;
  11.         cout << "b:" << b << endl;
  12.        
  13.         return 0;
  14. }
复制代码
  1. 请输入内容:
  2. 012345678
  3. a:012345678
  4. b:
复制代码

输入01234568时,a被赋值为012345678,留下换行符在缓冲区,遇到第二个cin.get(b,10)时,b自动接收这个换行符而没有被赋值,导致程序出错

cin.getline
  1. #include <iostream>

  2. using namespace std;

  3. int main()
  4. {
  5.         char a[10],b[10];

  6.         cout << "请输入内容:" << endl;
  7.         cin.getline(a,10);
  8.         cin.getline(b,10);
  9.        
  10.         cout << "a:" << a << endl;
  11.         cout << "b:" << b << endl;
  12.        
  13.         return 0;
  14. }
复制代码
  1. 请输入内容:
  2. 012345678
  3. 012345678
  4. a:012345678
  5. b:012345678
复制代码

而cin.getline则不会把换行符留在缓冲区,使得能输入两次012345678使得a,b都赋值

那使用cin.get时如何让换行符不留在缓冲区呢,可以写一个空的cin.get来清除这个换行符,如下
  1. #include <iostream>

  2. using namespace std;

  3. int main()
  4. {
  5.         char a[10],b[10];

  6.         cout << "请输入内容:" << endl;
  7.         cin.get(a,10);
  8.         cin.get();
  9.         cin.get(b,10);
  10.        
  11.         cout << "a:" << a << endl;
  12.         cout << "b:" << b << endl;
  13.        
  14.         return 0;
  15. }
复制代码

对于cin.get与cin.getline还有一种用法,如下
  1. #include <iostream>

  2. using namespace std;

  3. int main()
  4. {
  5.         char a[10],b[10];

  6.         cout << "请输入内容:" << endl;
  7.         cin.get(a,10,'#');
  8.         cin.get(b,10);
  9.        
  10.         cout << "a:" << a << endl;
  11.         cout << "b:" << b << endl;
  12.        
  13.         return 0;
  14. }
复制代码
  1. 请输入内容:
  2. 012#14225
  3. a:012
  4. b:#14225
复制代码

这个第三个参数的作用是但遇到第三个参数的值是自动把其转变为换行并把这个字符留在缓冲区,当用于cin.getline时,这样#就不见了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-2 00:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表