【问题标题】:cin is not taking in the last input in a while loopcin 没有接受 while 循环中的最后一个输入
【发布时间】:2020-11-09 08:56:39
【问题描述】:

在以下代码段中,while 循环内的 cin 嵌套在 main 函数中的 while 循环内,在最后一次输入期间(即,当 @987654326 @) 并改为报告分段错误。

我通过使用print 语句(在下面的代码中注释)来解决这个问题,一个在内部while 循环的开头,一个在cin 语句之后(查找读取的值vx 减 1) 和 while 循环外。第三个cout 语句没有执行,由此我断定分段错误在while 循环内。

此外,在内部while 循环的最后一次迭代中,cin 语句之后的cout 语句(用于打印vx 的值)也没有执行。因此,我认为内部 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 &lt;bits/stdc++.h&gt; is a horrible idea.
  • 不要在不需要的情况下做“清除和忽略”的事情。将其作为自动咒语执行可能会导致错误。
  • 只有在输入无效输入时,才需要忽略和清除调用以从失败状态恢复蒸汽
  • 分段错误可能是由最后一次 cin 读取后的错误引起的。 cout
  • @SaketSingh 与其将cout 语句放入代码中,不如学习如何使用调试器。这通常是一种比使用cout 更可靠的方法来追踪错误。如果你确实使用了cout,那么记得每次都刷新输出,否则当你崩溃的时候你可能看不到所有的输出。

标签: c++ input while-loop cin


【解决方案1】:

错误在这里

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 --;
}

通过修改 unordered_set leaf[node].erase(it);,您将使基于范围的 for 循环使用的隐式迭代器无效。用一个显式迭代器重写你的循环,这样你就可以解决迭代器失效的问题。像这样

for (auto i = leaf[node].begin(); i != leaf[node].end(); ) {
    if(temp == 0) break;
    auto it = *i;
    i = leaf[node].erase(i);
    auto j = find(adj[node].begin(), adj[node].end(), it);
    adj[node].erase(j);
    temp --;
}

通过这个循环,您的代码将运行完成(至少对我而言)。我不知道输出是否正确。

【讨论】:

  • 非常感谢您指出这一点,您能否也请您告诉为什么它是非法的!但是,我猜这个答案与我的问题无关。能否请您再次检查问题!在最后一个输入之前存在分段错误,并且这个基于范围的 for 循环根本不会运行!
  • @SaketSingh 我运行了你的代码,但在上述循环中出现错误。您的代码中可能还有其他错误。
  • 请问您是运行了整个代码还是只运行了 for 循环?如果你已经运行了整个代码,你能告诉你使用的是哪个版本的编译器吗?我已经在 onlinegdb.com 的 C++17 上进行了尝试,并且在输入中出现错误,并且基于范围的 for 循环在错误之前没有执行(问题是关于这个错误)。能否请您提供一些参考,让我了解为什么这个 for 循环不正确?
  • @SaketSingh 我希望您遇到的问题是,如果您的代码崩溃,那么您不一定会看到程序的所有输出。因此,您的崩溃似乎比实际更早。随着对上面循环的更改,我的代码运行完成。
  • @SaketSingh 这里是关于基于范围的循环如何实际工作的链接en.cppreference.com/w/cpp/language/range-for,这里是关于迭代器失效的链接。 en.cppreference.com/w/cpp/container
猜你喜欢
  • 2019-08-11
  • 1970-01-01
  • 2016-04-26
  • 2017-03-25
  • 2013-01-06
  • 2020-09-12
  • 2020-08-08
  • 2013-06-05
  • 1970-01-01
相关资源
最近更新 更多