C++ 输入函数大乱斗:cin.get、cin.getline、getline 的区别与记忆技巧

Ryan Lu Lv4

前言

学习 C++ 输入输出时,cin.get()cin.getline()getline() 这三个函数常常让人混淆。它们都能读取输入,但行为却各不相同。本文通过对比分析和实用示例,帮你彻底理清它们的区别,并提供简单的记忆方法。

三个函数的快速对比

函数所属语法读取内容处理换行符
cin.get()istream 成员cin.get(buf, size)包含换行符留在缓冲区
cin.getline()istream 成员cin.getline(buf, size)不包含换行符读取并丢弃
getline()全局函数getline(cin, str)不包含换行符读取并丢弃
cin >>运算符重载cin >> var遇到空白停止留在缓冲区

函数详解

1. cin.get()

语法

1
2
3
4
5
6
7
8
// 读取单个字符
char ch = cin.get();

// 读取到字符数组
cin.get(char* buf, int size);

// 读取到指定分隔符
cin.get(char* buf, int size, char delim);

特点

  • 读取 size - 1 个字符或遇到换行符停止
  • 换行符留在输入缓冲区
  • 读取的内容包含换行符(如果用单字符版本)

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
using namespace std;

int main() {
char buf[20];

cout << "输入:Hello World\n";
cin.get(buf, 20);

cout << "读取内容:[" << buf << "]" << endl;

// 缓冲区还有换行符
char next = cin.get();
cout << "下一个字符是换行符:" << (next == '\n' ? "YES" : "NO") << endl;

return 0;
}

输出

1
2
3
输入:Hello World
读取内容:[Hello World]
下一个字符是换行符:YES


2. cin.getline()

语法

1
2
3
4
5
// 读取到字符数组,默认以换行符结束
cin.getline(char* buf, int size);

// 读取到指定分隔符
cin.getline(char* buf, int size, char delim);

特点

  • 读取 size - 1 个字符或遇到换行符停止
  • 换行符被读取并丢弃(不在缓冲区,也不在 buf 中)
  • 只能用于字符数组(C 风格字符串)

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
using namespace std;

int main() {
char buf[20];

cout << "输入:Hello World\n";
cin.getline(buf, 20);

cout << "读取内容:[" << buf << "]" << endl;

// 缓冲区已无换行符
cout << "准备读取下一个输入..." << endl;

return 0;
}

3. getline() - 全局函数

语法

1
2
3
4
5
// 读取到 string 对象
getline(istream& is, string& str);

// 读取到指定分隔符
getline(istream& is, string& str, char delim);

特点

  • 读取整行,自动扩展 string 大小
  • 换行符被读取并丢弃
  • 只能用于std::string 类型
  • 全局函数,不是成员函数

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>
using namespace std;

int main() {
string str;

cout << "输入:Hello World from string!\n";
getline(cin, str);

cout << "读取内容:[" << str << "]" << endl;
cout << "长度:" << str.length() << endl;

return 0;
}

核心区别对比实验

实验 1:换行符去哪了?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <string>
using namespace std;

int main() {
char buf[50];
string str;

cout << "=== 测试 cin.get() ===" << endl;
cout << "请输入一行:";
cin.get(buf, 50);
cout << "buf: [" << buf << "]" << endl;
cout << "下一个字符 ASCII: " << (int)cin.get() << endl; // 10 = '\n'

cout << "\n=== 测试 cin.getline() ===" << endl;
cin.ignore(); // 清空缓冲区
cout << "请输入一行:";
cin.getline(buf, 50);
cout << "buf: [" << buf << "]" << endl;
cout << "下一个字符 (按任意键): ";
char ch = cin.get(); // 会等待用户输入
cout << "你按了: " << ch << endl;

cout << "\n=== 测试 getline() ===" << endl;
cout << "请输入一行:";
getline(cin, str);
cout << "str: [" << str << "]" << endl;
cout << "下一个字符 (按任意键): ";
ch = cin.get(); // 会等待用户输入
cout << "你按了: " << ch << endl;

return 0;
}

实验 2:混合使用 cin >> 后的问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>
using namespace std;

int main() {
int age;
char buf[50];
string str;

cout << "输入年龄:";
cin >> age; // 输入 18 后按回车

cout << "cin.get() 读取:";
cin.get(buf, 50); // 读到的是空字符串!
cout << "[" << buf << "]" << endl;

cout << "再次用 getline(cin) 读取:";
getline(cin, str); // 也是空字符串!
cout << "[" << str << "]" << endl;

return 0;
}

问题原因cin >> 只读取数字,换行符留在缓冲区,后续的 get 类函数立即读到换行符就结束了。

解决方案

1
2
3
4
cin >> age;
cin.ignore(); // 忽略缓冲区中的换行符
// 或者
cin.ignore(1000, '\n'); // 忽略最多 1000 字符或直到换行符


一图总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌─────────────────────────────────────────────────────────────┐
│ 输入:"ABC\n" │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
cin.get() cin.getline() getline(cin)
char buf[] char buf[] string str
│ │ │
▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐
│ "ABC\n"│ │ "ABC" │ │ "ABC" │
└────────┘ └────────┘ └────────┘
│ │ │
换行符在 buf 中 换行符被丢弃 换行符被丢弃
│ │ │
▼ ▼ ▼
缓冲区:空 缓冲区:空 缓冲区:空

记忆技巧

技巧 1:看函数名

1
2
3
cin.get()     → get = 获取 → 来者不拒,换行符也要
cin.getline() → getline 但用 cin. → 字符数组版,丢弃换行
getline() → 全局函数 → string 专用,丢弃换行

技巧 2:看参数类型

1
2
3
cin.get(buf, size)      // buf 是 char[] → 保留换行
cin.getline(buf, size) // buf 是 char[] → 丢弃换行
getline(cin, str) // str 是 string → 丢弃换行

记忆口诀: > 有 cin 点的是小弟(留换行) > 没 cin 点的是大哥(丢换行) > string 只能用全局 getline

技巧 3:场景联想

场景选择
读取单个字符cin.get()
C 风格字符串,需要换行符cin.get()
C 风格字符串,不要换行符cin.getline()
C++ string,读一行getline(cin, str)
读取数字后读字符串cin >> x; cin.ignore(); getline(cin, str);

常见陷阱与解决方案

陷阱 1:cin >> 后直接 getline

1
2
3
4
5
6
7
8
9
10
11
12
// ❌ 错误写法
int n;
string s;
cin >> n;
getline(cin, s); // s 是空的!

// ✅ 正确写法
int n;
string s;
cin >> n;
cin.ignore(); // 或 cin.ignore(1000, '\n');
getline(cin, s);

陷阱 2:连续使用 cin.get()

1
2
3
4
5
6
7
8
9
10
// ❌ 问题代码
char buf1[50], buf2[50];
cin.get(buf1, 50);
cin.get(buf2, 50); // buf2 会是空的!

// ✅ 解决
char buf1[50], buf2[50];
cin.get(buf1, 50);
cin.ignore(); // 忽略第一个 get 留下的换行符
cin.get(buf2, 50);

陷阱 3:混淆返回值

1
2
3
4
5
6
7
8
// cin.get() 返回 istream&,可以链式调用
cin.get(buf, 50).get(ch); // 合法

// getline() 返回 istream&,也可以链式
getline(cin, str1).getline(cin, str2); // ❌ 错误!getline 不是成员函数
// ✅ 应该这样
getline(cin, str1);
getline(cin, str2);

完整示例程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
#include <string>
#include <cstring>
using namespace std;

void test_cin_get() {
cout << "\n=== cin.get() 测试 ===" << endl;
char buf[100];

cout << "请输入一行文字:";
cin.get(buf, 100);

cout << "读取内容:[" << buf << "]" << endl;
cout << "长度:" << strlen(buf) << endl;

// 检查是否有换行符
int len = strlen(buf);
if (len > 0 && buf[len-1] == '\n') {
cout << "提示:内容包含换行符" << endl;
}
}

void test_cin_getline() {
cout << "\n=== cin.getline() 测试 ===" << endl;
char buf[100];

cin.ignore(1000, '\n'); // 清空缓冲区
cout << "请输入一行文字:";
cin.getline(buf, 100);

cout << "读取内容:[" << buf << "]" << endl;
cout << "长度:" << strlen(buf) << endl;
cout << "提示:换行符已被丢弃" << endl;
}

void test_std_getline() {
cout << "\n=== getline(cin, str) 测试 ===" << endl;
string str;

cout << "请输入一行文字:";
getline(cin, str);

cout << "读取内容:[" << str << "]" << endl;
cout << "长度:" << str.length() << endl;
cout << "提示:换行符已被丢弃" << endl;
}

int main() {
cout << "========================================" << endl;
cout << " C++ 输入函数对比测试程序" << endl;
cout << "========================================" << endl;

test_cin_get();
test_cin_getline();
test_std_getline();

cout << "\n========================================" << endl;
cout << " 测试完成!" << endl;
cout << "========================================" << endl;

return 0;
}

总结表格

特性cin.get()cin.getline()getline()
类型成员函数成员函数全局函数
目标类型char/char[]char[]string
换行符处理留在缓冲区读取并丢弃读取并丢弃
是否包含换行
自动扩容
指定分隔符支持支持支持
推荐场景字符/保留换行C 风格字符串C++ string

终极记忆口诀

1
2
3
4
5
6
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
cin 后面有个点,换行留在缓冲区
直接调用 getline,换行自动被丢弃
string 只能用全局,char 数组用成员
cin >> 后要 ignore,否则 getline 会出错
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

记住这个口诀,这三个函数再也难不倒你!


参考资源: - C++ Reference - istream::get - C++ Reference - istream::getline - C++ Reference - std::getline

  • Title: C++ 输入函数大乱斗:cin.get、cin.getline、getline 的区别与记忆技巧
  • Author: Ryan Lu
  • Created at : 2026-03-16 00:00:00
  • Updated at : 2026-03-16 07:36:22
  • Link: http://ryan-hub.site/e42f3df329ee/
  • License: This work is licensed under CC BY-NC-SA 4.0.