【问题标题】:stoi "terminate called after throwing an instance of 'std::invalid argument'stoi "在抛出一个 'std::invalid argument' 的实例后调用终止
【发布时间】:2015-11-21 09:21:37
【问题描述】:

我目前正在研究一个动态编程问题,我决定用 C++ 而不是我通常的 Java/C# 来编写它以提高我的技能。 但是,我遇到了一个我无法弄清楚的错误。编辑:我将在这里发布我的整个解决方案:

int main() {
    /* Enter your code here. Read input from STDIN. Print output to STDOUT */
    int linecounter = 0;
    int value = -1;
    int differentCoins = -1;
    int uniqueCoinCount = -1;
    std::vector<std::vector<int>> array;
    int *uniqueCoins;
    int totalAmount = -1;

    for (std::string line; std::getline(std::cin, line); ) {
        if (linecounter % 2 == 0) {
            string inputs[2];
            int i = 0;
            stringstream ssin(line);
            while (ssin.good() && i < 2){
                ssin >> inputs[i];
                ++i;
            }
            cout << inputs[0];
            cout << inputs[1];
            totalAmount = std::stoi(inputs[0]);
            uniqueCoinCount = std::stoi(inputs[1]);
            uniqueCoins = new int[uniqueCoinCount + 1];

        }
        if (linecounter % 2 == 1) {
            array.resize(uniqueCoinCount + 1, std::vector<int>(totalAmount + 1));
            for (int i = 0; i < totalAmount; i++) {
                array[i][0] = 0;
            }
            for (int i = 0; i <= uniqueCoinCount; i++) {
                array[0][i] = 1;
            }


            stringstream ssin(line);
            int coinCounter = 0;
            uniqueCoins[coinCounter] = 0;
            coinCounter++;
            while (ssin.good() && coinCounter < uniqueCoinCount + 1){

                ssin >> uniqueCoins[coinCounter];
                coinCounter++;
            }

            for (int i = 1; i < totalAmount; i++) {
                for (int j = 1; j <= uniqueCoinCount; j++) {
                    int totalExcludingCoin = array[i][j - 1];
                    if (uniqueCoins[j] <= i) {
                        array[i][j] = totalExcludingCoin + array[i - uniqueCoins[j]][j];
                    }
                    else {
                        array[i][j] = totalExcludingCoin;
                    }
                }
            }
        }
        linecounter++;
    }

    //cout << array[totalAmount][uniqueCoinCount + 1];
}

当我使用cout &lt;&lt; inputs[0] 时,我可以看到它打印出4。但是,hackerrank 编译器给了我一个错误提示

"在抛出 'std::invalid_argument'的实例后调用终止
what(): stoi"

可能是什么问题?我也试过atoi(),它返回我40而不是4,可能是因为atoi在出错时返回0?是因为它读取了空终止符还是什么?

谢谢

这是hackerrank的输出:

不错的尝试,但你没有通过这个测试用例。 输入(标准输入) 4 3 1 2 3 你的输出(标准输出) 43 预期产出 4 编译器消息 中止调用 错误(标准错误) 在抛出 'std::invalid_argument' 的实例后调用终止 什么():stoi

【问题讨论】:

  • 字符串的内容是什么?
  • cout
  • 你的循环表现出istream::eof错误,伪装得很薄(使用good而不是!eof作为循环条件)。循环应该是while ( ssin &gt;&gt; inputs[i] &amp;&amp; ++i &lt; 2 ) {}(或for 循环)
  • 更新发布的代码以包含您提到的输出语句,并发布输出(并验证确切的发布代码生成该输出)。最好发布MCVE。您的代码是正确的,因此问题很可能是 line 实际上不包含您认为的内容,或者包含一些不可打印的字符或您没有注意到的字符。
  • 你可以 hexdump line 并寻找奇怪的字符

标签: c++


【解决方案1】:
        while (ssin.good() && i < 2){
            ssin >> inputs[i];
            ++i;
        }

您正在使用状态报告功能来预测未来。 good 函数不会告诉您未来操作的结果是什么,只会告诉您过去操作的结果。您需要实际检查操作 (ssin &gt;&gt; inputs[i]) 是否成功,而不是假设过去的流良好就一定会成功。

【讨论】:

    【解决方案2】:

    在竞技编程中,出于速度原因习惯使用scanf:http://www.cplusplus.com/reference/cstdio/scanf/

    另一个好方法是使用 cin。我相信它有点慢,但我已经过得很好。

    从标准输入读取大多数比赛的示例代码。

    int main() {
      int n;
      cin >> n;
    
      std::vector<int> xs(n);
      for (int i = 0; i < n; ++i) { 
        cin >> xs[i];
      }
      // do actual computation
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      • 2020-12-27
      • 1970-01-01
      • 1970-01-01
      • 2021-01-02
      • 2018-01-06
      • 2017-03-08
      相关资源
      最近更新 更多