Content #
需要读入的数据如下:
4
1 2 3 4
2 1 3
3 1 2 4
4 1 3
0
0
最开始的数字N,表示图的节点的个数,接下来若干行。每行的第1个数字表示起点u,后续的数字v表示从u开始到v有一条边。如果第1个数字为0,表示图的输入结束。
读取的代码如下:
int N;
while (cin >> N && N > 0) {
string s;
while (getline(cin, s)) {
istringstream iss(s);
int u;
iss >> u;
if (u == 0) break;
int v;
while (iss >> v) {
//...
}
}
}
上面的代码存在换行符陷阱。读取N后,第1行的换行符还在,接下来调用 getline时,会得到空行,第1轮循环会马上结束,进入第2轮循环后会将第2行的第1个数字当作N读进来,导致数据读取错误。
解决方法是在读取N后,调用cin.ignore()来丢弃换行符:
int N;
while (cin >> N && N > 0) {
cin.ignore(); //忽略当前的换行符,没有这一句,第一次调用getline会得到空行。
//...
}
getline官方文档说明: When consuming whitespace-delimited input (e.g. int n; std::cin >> n;) any whitespace that follows, including a newline character, will be left on the input stream. Then when switching to line-oriented input, the first line retrieved with getline will be just that whitespace. In the likely case that this is unwanted behaviour, possible solutions include:
- An explicit extraneous initial call to getline.
- Removing consecutive whitespace with std::cin >> std::ws.
- Ignoring all leftover characters on the line of input with cin.ignore(std::numeric_limits<std::streamsize>::max(), ‘\n’);.