为什么 getline() 函数在这里不读取任何内容?
Why doesn't the getline() function read anything here?
对于输入,
1
4 2
1 2
1 3
1
计划,
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int Q;
cin >> Q; //Q=2
while(Q--)
{
int N, E;
cin >> N >> E; // N=4, E=2
while(1)
{
string edge;
getline(cin,edge); //edge should store "1 2" for the first iteration and "1 3" for the second iteration.
cout << edge << " " << edge.size() << endl;
vector<int> adjList[N];
if(edge.size()>1)
{
int u = stoi(edge.substr(0,1));
int v = stoi(edge.substr(2,1));
for(int i=0; i<E; ++i)
{
adjList[u].push_back(v);
adjList[v].push_back(u);
}
}
else
break;
}
}
return 0;
}
给出输出
0
程序应该打印出来,
1 2 3
1 3 3
1 1
为什么我没有在字符串 edge 中存储任何值?我认为是 getline()
函数导致了问题。是否有其他函数可以将整行作为一个字符串(包括空格)直到到达换行符?
执行这条语句后:
cin >> N >> E; // N=4, E=2
输入流中的下一个是换行符,将 int 读入 E
不会消耗它。所以第一次调用 getline(cin, edge)
只是读取那个换行符,它是一个空字符串。
您需要从流中读取更多数据,以便对 getline
的第一次调用读取一个新行,而不是读取 N
和 E
后剩下的任何内容。
你可以这样做:
cin >> N >> E; // N=4, E=2
string dummy;
getline(cin, dummy); // read rest of line
这会将换行符读取到虚拟变量中,因此下一次读取将从下一行开始。
或者像这样:
cin >> N >> E; // N=4, E=2
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
这将告诉 cin
流丢弃字符,直到:
- 它已阅读
std::numeric_limits<std::streamsize>::max()
个字符(这是一个非常非常大的数字),或者
- 它读取一个
\n
字符(即下一个换行符)。
同样,这意味着下一次读取将从下一行开始。
因为你知道读入 E
的值和换行符之间没有白色 space 或其他数据,你不需要丢弃非常非常多的字符并且你实际上可以使它更简单:
cin >> N >> E; // N=4, E=2
cin.ignore(20, '\n');
这将最多丢弃 20 个字符,或下一个换行符,以先到者为准。
如果您完全确定在换行符之前 什么都没有,您可以忽略一个字符:
cin >> N >> E; // N=4, E=2
cin.ignore(); // discard a single character
这应该适用于您的情况,但有点脆弱,因为如果有人将 space 插入您的输入文件,事情将再次停止工作。
对于输入,
1
4 2
1 2
1 3
1
计划,
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int Q;
cin >> Q; //Q=2
while(Q--)
{
int N, E;
cin >> N >> E; // N=4, E=2
while(1)
{
string edge;
getline(cin,edge); //edge should store "1 2" for the first iteration and "1 3" for the second iteration.
cout << edge << " " << edge.size() << endl;
vector<int> adjList[N];
if(edge.size()>1)
{
int u = stoi(edge.substr(0,1));
int v = stoi(edge.substr(2,1));
for(int i=0; i<E; ++i)
{
adjList[u].push_back(v);
adjList[v].push_back(u);
}
}
else
break;
}
}
return 0;
}
给出输出
0
程序应该打印出来,
1 2 3
1 3 3
1 1
为什么我没有在字符串 edge 中存储任何值?我认为是 getline()
函数导致了问题。是否有其他函数可以将整行作为一个字符串(包括空格)直到到达换行符?
执行这条语句后:
cin >> N >> E; // N=4, E=2
输入流中的下一个是换行符,将 int 读入 E
不会消耗它。所以第一次调用 getline(cin, edge)
只是读取那个换行符,它是一个空字符串。
您需要从流中读取更多数据,以便对 getline
的第一次调用读取一个新行,而不是读取 N
和 E
后剩下的任何内容。
你可以这样做:
cin >> N >> E; // N=4, E=2
string dummy;
getline(cin, dummy); // read rest of line
这会将换行符读取到虚拟变量中,因此下一次读取将从下一行开始。
或者像这样:
cin >> N >> E; // N=4, E=2
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
这将告诉 cin
流丢弃字符,直到:
- 它已阅读
std::numeric_limits<std::streamsize>::max()
个字符(这是一个非常非常大的数字),或者 - 它读取一个
\n
字符(即下一个换行符)。
同样,这意味着下一次读取将从下一行开始。
因为你知道读入 E
的值和换行符之间没有白色 space 或其他数据,你不需要丢弃非常非常多的字符并且你实际上可以使它更简单:
cin >> N >> E; // N=4, E=2
cin.ignore(20, '\n');
这将最多丢弃 20 个字符,或下一个换行符,以先到者为准。
如果您完全确定在换行符之前 什么都没有,您可以忽略一个字符:
cin >> N >> E; // N=4, E=2
cin.ignore(); // discard a single character
这应该适用于您的情况,但有点脆弱,因为如果有人将 space 插入您的输入文件,事情将再次停止工作。