【发布时间】:2020-11-09 08:56:39
【问题描述】:
在以下代码段中,while 循环内的 cin 嵌套在 main 函数中的 while 循环内,在最后一次输入期间(即,当 @987654326 @) 并改为报告分段错误。
我通过使用print 语句(在下面的代码中注释)来解决这个问题,一个在内部while 循环的开头,一个在cin 语句之后(查找读取的值v 和 x 减 1) 和 while 循环外。第三个cout 语句没有执行,由此我断定分段错误在while 循环内。
此外,在内部while 循环的最后一次迭代中,cin 语句之后的cout 语句(用于打印v 和x 的值)也没有执行。因此,我认为内部 while 循环中的 cin 在最后一次迭代中不起作用。
我尝试了很多搜索并输入了cin.clear() 和cin.ignore(numeric_limits<streamsize>::max(), '\n'); 语句,但仍然没有用!
为什么会出现这样的问题?
#include <bits/stdc++.h>
using namespace std;
vector <vector<int>> adj;
vector<unordered_set <int>> leaf;
int process(int node, int *pans, int k){
*pans = *pans + (leaf[node].size() / k) * k;
int temp = (leaf[node].size() / k) * k;
if(temp == 0) return 0;
for(auto it : leaf[node]){
if(temp == 0) break;
leaf[node].erase(it);
auto j = find(adj[node].begin(), adj[node].end(), it);
adj[node].erase(j);
temp --;
}
if(adj[node].size() == 1){
leaf[adj[node][0]].insert(node);
process(adj[node][0], pans, k);
}
return 0;
}
int main(){
int t, v, x, n, k;
cin>>t;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
while(t--){
int ans = 0;
cin>>n>>k;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
adj.resize(n);
int h = 1;
while(h < n){
// cout<<"r";
cin>>v>>x;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
v --; x --;
cout<<v<<" "<<x<<"\n";
adj[v].push_back(x);
adj[x].push_back(v);
h++;
}
// cout<<"out";
leaf.resize(n);
for(int i = 0; i < n; i ++){
if(adj[i].size() == 1) leaf[adj[i][0]].insert(i);
}
for(int i = 0; i < n; i ++){
if(leaf[i].size() >= k) process(i, &ans, k);
}
cout<<ans<<"\n";
adj.clear();
leaf.clear();
}
}
以下是输入示例:
1
8 3
1 2
1 5
7 6
6 8
3 1
6 4
6 1
【问题讨论】:
-
请尽量减少这里的代码量。例如,您说您的问题出在输入中,因此您没有理由展示处理数据的代码。另外,
#include <bits/stdc++.h>is a horrible idea. -
不要在不需要的情况下做“清除和忽略”的事情。将其作为自动咒语执行可能会导致错误。
-
只有在输入无效输入时,才需要忽略和清除调用以从失败状态恢复蒸汽
-
分段错误可能是由最后一次 cin 读取后的错误引起的。 cout
-
@SaketSingh 与其将
cout语句放入代码中,不如学习如何使用调试器。这通常是一种比使用cout更可靠的方法来追踪错误。如果你确实使用了cout,那么记得每次都刷新输出,否则当你崩溃的时候你可能看不到所有的输出。
标签: c++ input while-loop cin