在 C 和 C++ 中,不同输入函数对 空格 和 换行符(' '
和 '\n'
)的处理方式对比:
1. C 语言函数(<stdio.h>
)
scanf("%s")
- 行为:读取非空白字符(遇到空格/换行停止),不消费换行符。
-
示例:
char str[100]; scanf("%s", str); // 输入 "hello world" → 只读取 "hello"
- 注意:换行符会留在输入缓冲区,影响后续读取。
scanf("%c")
- 行为:读取单个字符(包括空格/换行符)。
-
示例:
char c; scanf("%c", &c); // 输入 '\n' 会直接读取换行符
fgets()
- 行为:读取一行(包括换行符),换行符会存入缓冲区。
-
示例:
char line[100]; fgets(line, 100, stdin); // 输入 "abc" → line = "abc\n\0"
getchar()
- 行为:读取任意字符(包括空格/换行符)。
-
示例:
int c = getchar(); // 读取单个字符(可能是 '\n')
2. C++ 函数(<iostream>
)
std::cin >> var
- 行为:跳过前导空白(空格/换行),读取到下一个空白符停止,不消费换行符。
-
示例:
std::string s; std::cin >> s; // 输入 " hello\n" → s = "hello",换行符留在缓冲区
std::getline(std::cin, str)
-
行为:读取一行(默认以
'\n'
结束),丢弃换行符(不存入str
)。 -
示例:
std::string line; std::getline(std::cin, line); // 输入 "abc" → line = "abc"
(头文件是#include<string>)
cin.get()
- 行为:读取单个字符(包括空格/换行符)。
-
示例:
char c = std::cin.get(); // 读取任意字符(可能是 '\n')
cin.getline(char*, size)
-
行为:读取一行到字符数组,丢弃换行符(与
std::getline
类似)。 -
示例:
char arr[100]; std::cin.getline(arr, 100); // 输入 "abc" → arr = "abc\0"
(头文件是#include <iostream>)
关键对比表
函数 | 是否跳过前导空白? | 遇到空格停止? | 遇到换行停止? | 换行符处理方式 |
---|---|---|---|---|
scanf("%s") |
是 | 是 | 是 | 留在缓冲区 |
scanf("%c") |
否 | 否 | 否 | 读取为字符 |
fgets() |
否 | 否 | 是 | 存入缓冲区 |
std::cin >> var |
是 | 是 | 是 | 留在缓冲区 |
std::getline() |
否 | 否 | 是 | 丢弃(不存入字符串) |
cin.get() |
否 | 否 | 否 | 读取为字符 |
cin.getline(char*) |
否 | 否 | 是 | 丢弃(不存入数组) |
常见问题与解决方案
1. 混合使用 cin >>
和 getline()
-
问题:
cin >>
不消费换行符,导致后续getline()
读到空行。 -
解决:用
cin.ignore()
清空缓冲区:int num; std::string line; std::cin >> num; std::cin.ignore(); // 忽略换行符 std::getline(std::cin, line);
2. 读取包含空格的字符串
-
C:用
fgets()
(注意换行符会存入字符串)。 -
C++:直接用
std::getline(std::cin, str)
。
3. 逐个字符读取(包括空格/换行)
-
C:
getchar()
或scanf("%c")
。 -
C++:
cin.get()
。
总结
-
跳过空白:
cin >>
和scanf("%s")
会忽略前导空格/换行。 -
保留空白:
fgets()
、getline()
、getchar()
会读取空格/换行。 -
换行符处理:
fgets()
存入缓冲区,getline()
丢弃,cin >>
留在缓冲区。
根据需求选择合适函数,并注意缓冲区残留的换行符!