Строка parse, содержащая числа в целочисленный массив

Строка задается как входной элемент, который состоит из чисел, и я хочу преобразовать его в целые массивы в С++.

#include <string>
#include <iostream>
#include <sstream>

using std::string;
using std::stringstream;
using std::cout;
using std::endl;

int main(int argc,char** argv) {

    string num="-24 2 90 24 50 76";

    stringstream stream(num);

    while(stream){
        int n;
        stream>>n;
        cout<<n<<endl;
    }

    return 0;
}

Выход (GCC):

-24 2 90 24 50 76 76

Почему я получаю дополнительную ценность и что является эффективным для преобразования их в целочисленный массив?

UPDATE:

Что делать, если поток строк содержит разделитель, отличный от пробела. Как это проанализировать? Например:  string num="-24,2,90,24,50,76";

Ответы

Ответ 1

Конец условия файла не задан при успешном анализе, вы должны проверить состояние потока после разбора.

Второй 76 - это, по сути, просто чистый шанс. Несовершенный синтаксический анализ оставляет целевой операнд нетронутым, и поскольку вы не инициализировали n, это может быть что угодно.

Быстрое исправление:

stream>>n;
if (stream)
    cout<<n<<endl;

Чистое исправление:

int n;
while(stream >> n){
    cout<<n<<endl;
}

Чтобы сохранить эти целые числа, канонический способ - использовать std::vector, если количество элементов неизвестно. Пример использования:

std::vector<int> values;
int n;
while(stream >> n){
    ...do something with n...
    values.push_back(n);
}

Однако вы можете использовать итераторы поверх потоков и использовать следующее:

// Use std::vector range constructor
std::vector<int> values(
     (std::istream_iterator<int>(stream)), // begin
     (std::istream_iterator<int>()));      // end

Ответ 2

Я не знаю, найдете ли вы ответ на свой обновленный вопрос или нет. если вы этого не сделаете, вы можете легко сделать это с помощью кода

for (string::iterator it = num.begin(); it != num.end(); ++it) {
    if (*it == ',') {
        *it = ' ';
    }
    else continue;
}

этот код удаляет все ваши двоеточия и заменяет их пробелом. то вы можете сделать только нормально

Ответ 3

Еще одно средство обращения с целым числом, разделенным символом, с использованием вектора, который даже, возможно, немного более упрощен, более похож на это:

string str = "50,2,25,38,9,16";
vector<int> ints;
stringstream ss(str);
int n;
char ch;

while(ss >> n) {
    if(ss >> ch)
        ints.push_back(n);
    else
        ints.push_back(n);
}

таким образом вы можете сначала пройти через любое разделение символов (если они есть), а затем по умолчанию вернуться к захвату целых чисел и добавлению их в список, если они этого не сделают (AKA - конец списка)