C++ 为什么我会得到一个超时(使用sstream解析由逗号分隔的整数列表)?

C++ 为什么我会得到一个超时(使用sstream解析由逗号分隔的整数列表)?,c++,timeout,stringstream,sstream,C++,Timeout,Stringstream,Sstream,我得到一个由n个整数组成的输入字符串,用逗号分隔(例如“23,4,56”)。我需要设置一个stringstream来表示这个字符串,然后使用它将每个整数扫描成一个向量。向量的元素(列表中的整数)最终将逐行输出。我得到main(),只负责编写parseInt(string str)。出于某种原因,我总是被暂停。我猜这是我的while循环中的一些东西,特别是关于我如何使用str()操作我的sstream,但我不能确切地知道到底发生了什么。我是新的SfSand和C++,所以任何帮助都将被赏识! #in

我得到一个由n个整数组成的输入字符串,用逗号分隔(例如“23,4,56”)。我需要设置一个stringstream来表示这个字符串,然后使用它将每个整数扫描成一个向量。向量的元素(列表中的整数)最终将逐行输出。我得到main(),只负责编写parseInt(string str)。出于某种原因,我总是被暂停。我猜这是我的while循环中的一些东西,特别是关于我如何使用str()操作我的sstream,但我不能确切地知道到底发生了什么。我是新的SfSand和C++,所以任何帮助都将被赏识!
#include <sstream>
#include <vector>
#include <iostream>
using namespace std;

vector<int> parseInts(string str) {
    int a; //will use this to hold the value of the 1st int in the sstream
    stringstream list_initial; //will iterate over this sstream
    list_initial.str(str); //set sstream to represent input str
    vector<int> list_final; //will return this final vector for output in main
    while (!list_initial.str().empty()){ //stop iterating at end of string
        list_initial>>a; //store leading int value in a
        list_final.push_back(a); //add a to end of vector
        while (!ispunct(list_initial.str()[0])){ //get to next int in list
            list_initial.str(list_initial.str().erase(0,1));
        };
        list_initial.str(list_initial.str().erase(0,1)); //erase leading comma
    };
    return list_final;   
};

int main() {
    string str;
    cin >> str;
    vector<int> integers = parseInts(str);
    for(int i = 0; i < integers.size(); i++) {
        cout << integers[i] << "\n";
    }

    return 0;
}
#包括
#包括
#包括
使用名称空间std;
向量解析整数(字符串str){
int a;//将使用它保存sstream中第一个int的值
stringstream列表\u initial;//将迭代此sstream
list_initial.str(str);//将sstream设置为表示输入str
向量列表_final;//将返回此最终向量,以便在main中输出
而(!list_initial.str().empty()){//在字符串末尾停止迭代
list_initial>>a;//在a中存储前导int值
list_final.push_back(a);//将a添加到向量的末尾
而(!ispunct(list_initial.str()[0]){//get到列表中的下一个int
list_initial.str(list_initial.str().erase(0,1));
};
list_initial.str(list_initial.str().erase(0,1));//删除前导逗号
};
最终返回列表;
};
int main(){
字符串str;
cin>>str;
向量整数=解析整数(str);
对于(int i=0;icout您的函数实现可以得到真正的改进,但是按照您的逻辑,如果您替换第二行
,而
行:

        while (!ispunct(list_initial.str()[0])){ //get to next int in list
通过此项,添加长度检查:

        while (list_initial.str().size() && !ispunct(list_initial.str()[0])){ //get to next int in list
,然后is运行良好,运行良好,退出良好

解释 这个循环从未中断,因为在进程结束时,
ispunct()
函数从未将其参数
!list\u initial.str()[0]
识别为真:字符串
list\u initial.str()
此时为空,则
0
索引不存在。
请查看以下文件:

如果pos等于字符串长度,const版本不会抛出异常(无抛出保证)。
否则,会导致未定义的行为

您的程序被冻结,因为它没有找到可能导致离开上述循环的正确条件

忠告 关于您的问题,有一件重要的事情需要讨论:为什么您自己没有找到答案?这个问题的一个答案是:您没有尝试调试代码

为了回答您的问题,我刚刚调试了您的代码,并通过在代码周围添加此类行快速发现了问题,以查看发生了什么:

cout << "list_initial: " << list_initial.str() << endl;

cout流是一个抽象文件。它只是一组文本,可以被一些东西理解,例如,
cin>>n
将数字转换为整数

下面是如何使用流的一个想法:

#include <cctype>
#include <ciso646>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;

vector<int> parse_ints( const string& s )
{
  vector<int> ints;     // resulting list of ints
  istringstream ss(s);  // stream of ints separated by (non-digits)
  int n;                // each int extracted from the stream

  // while input an int
  while (ss >> n)
  {
    // save the int
    ints.push_back(n);

    // skip to next digit
    while (ss and !isdigit(ss.peek())) ss.get();
  }

  return ints;
}

int main()
{
  vector<int> xs = parse_ints( "2, 3 ,5; 7 : 11.13\t17abc21" );
  for (int x : xs)
    cout << x << " ";
  cout << "\n";
}
请注意,我们如何简单地跳过不感兴趣的字符?在这种特殊情况下,我们跳过所有非数字字符


希望这能有所帮助。

你说的“超时”是什么意思?如果你的代码运行缓慢,我怀疑这是因为你正在创建的所有std::string。std::stringstream和其他流一样,你应该这样对待它。你不需要继续创建str()或重置流的str()ing。你这是什么意思?我真的不明白流是如何工作的。我认为理想情况下,我可以编写一些只使用流成员函数的东西,这些函数在列表中读取,忽略逗号,并在列表末尾停止。我该怎么做?你通过创建和销毁新字符串不断修改流。你不需要这样做o做到这一点。请参见下面的代码演示。我明白了,非常感谢。我对编码是新手,所以调试技巧非常有用。你说我的函数实现可以改进,我对此很确定。我不认为我真的了解sstream或流在一般情况下是如何工作的。如果了解sstream,什么是优雅的实现什么?
#include <cctype>
#include <ciso646>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;

vector<int> parse_ints( const string& s )
{
  vector<int> ints;     // resulting list of ints
  istringstream ss(s);  // stream of ints separated by (non-digits)
  int n;                // each int extracted from the stream

  // while input an int
  while (ss >> n)
  {
    // save the int
    ints.push_back(n);

    // skip to next digit
    while (ss and !isdigit(ss.peek())) ss.get();
  }

  return ints;
}

int main()
{
  vector<int> xs = parse_ints( "2, 3 ,5; 7 : 11.13\t17abc21" );
  for (int x : xs)
    cout << x << " ";
  cout << "\n";
}
2 3 5 7 11 13 17 21