C++中使用二维char数组获取多行带空格字符串输入的异常问题
解决C++二维char数组读取多行含空格字符串的异常问题
这个问题我太熟悉啦!本质是输入缓冲区里的换行符在搞鬼,咱们一步步拆解解决:
问题根源
当你用cin >> n读取行数的时候,输入完数字后按下的回车(也就是换行符\n)会被留在输入缓冲区里。接下来调用cin.getline()时,它会直接读取这个残留的换行符,把它当成一行空输入——这就导致了:
- 当
n=1时,第一次getline直接读了空行,循环直接终止,看起来像没获取任何输入; - 当
n=2时,第一次getline读了空行(对应input[0]为空),第二次才读取你真正输入的那一行,所以只拿到一行有效内容。
解决方案
这里有几种简单有效的修复方式:
方法1:用cin.ignore()清空缓冲区的换行符
在cin >> n之后,专门加一行代码吃掉缓冲区里的换行符,确保后续的getline读取的是你真正输入的内容:
#include <iostream> #include <limits> // 必须包含这个头文件才能用numeric_limits using namespace std; int main() { char input[100][100]; int n, i; cout << "Enter no of lines : "; cin >> n; // 吃掉缓冲区中直到换行符的所有字符(只保留换行符之前的有效输入) cin.ignore(numeric_limits<streamsize>::max(), '\n'); cout << "Enter " << n << " sentences : " << endl; for(i = 0; i < n; i++) { cin.getline(input[i], 100); } // 测试打印输入内容 for(i = 0; i < n; i++) { cout << "Line " << i+1 << ": " << input[i] << endl; } return 0; }
方法2:全程用getline读取,再转换数字
如果不想处理缓冲区的问题,可以先读取整行字符串,再把它转换成整数n,这样就不会残留换行符:
#include <iostream> #include <sstream> #include <string> using namespace std; int main() { char input[100][100]; int n, i; string n_str; cout << "Enter no of lines : "; getline(cin, n_str); // 用stringstream把字符串转成整数 stringstream ss(n_str); ss >> n; cout << "Enter " << n << " sentences : " << endl; for(i = 0; i < n; i++) { cin.getline(input[i], 100); } // 测试打印 for(i = 0; i < n; i++) { cout << "Line " << i+1 << ": " << input[i] << endl; } return 0; }
额外小建议:用C++的vector<string>替代二维char数组
其实在C++里,用vector<string>来存储多行字符串会比二维char数组更安全、更灵活,不需要担心数组越界的问题,代码也更简洁:
#include <iostream> #include <vector> #include <string> #include <limits> using namespace std; int main() { vector<string> input; int n; cout << "Enter no of lines : "; cin >> n; cin.ignore(numeric_limits<streamsize>::max(), '\n'); cout << "Enter " << n << " sentences : " << endl; string line; for(int i = 0; i < n; i++) { getline(cin, line); input.push_back(line); } // 打印所有输入的行 for(int i = 0; i < n; i++) { cout << "Line " << i+1 << ": " << input[i] << endl; } return 0; }
内容的提问来源于stack exchange,提问作者sauravshah31




