Неправильный вывод с помощью std::string с использованием stoul для целочисленного массива

Привет, у меня возникли проблемы с попыткой преобразовать строку чисел, например: 100 101 102, в (stoul) динамически выделяемое целое число без знака; ожидается, что я могу получить доступ к номеру за номером в виде массива на входе переменной длины.

#include <iostream>
#include <new>
#include <string> //Memset
int console(){
    std::string console_buffer;
    unsigned long int* integersConverted = NULL;
    unsigned int integersNumberOf = 0;
    for( ; ; ){
        std::getline(std::cin, console_buffer);
        integersConverted = console_defaultSyntaxProcessing(console_buffer, &integersNumberOf);

        std::cout << "Found the following integers from conversion: ";
        for(unsigned int debug_tmp0 = 0; debug_tmp0 < integersNumberOf; debug_tmp0++){
            std::cout << integersConverted[debug_tmp0] << " ";
            std::cout << std::endl;
        }

        delete integersConverted;
        integersConverted = NULL;
    }
    return 0;
}

unsigned long int* console_defaultSyntaxProcessing(std::string console_buffer, unsigned int* integersNumberOfUpdate){
    *integersNumberOfUpdate = 0;
    unsigned int integersNumberOf = 0;
    unsigned long int* integersFound = NULL;
    integersFound = new unsigned long int(sizeof(unsigned long int) * 1024);
    std::size_t stringPosition = 0;
    for( ; stringPosition < console_buffer.length() && integersNumberOf < 1024; ){
        integersFound[integersNumberOf] = std::stoul(console_buffer, &stringPosition, 10); //10 = Decimal
        integersNumberOf++;
    }
    *integersNumberOfUpdate = integersNumberOf;
    return integersFound;
}

Я получаю правильное значение, если ввожу только одно число, но весь массив 1024 печатается, если я ввожу два числа или более, и все позиции получают первое целое число. Я пытался вручную установить функцию std::string в константу, обнулить console_buffer.length(), чтобы она нашла '\ 0' и т. д.; к сожалению не получилось..

ОБНОВЛЕНИЕ --- через 5 минут после первого сообщения в теме; Проблема в том, как ответил Яшас, в console_defaultSyntaxProcessing для цикла; stoul &stringPosition возвращает количество прочитанных символов, а не позицию std::string. Другая проблема с использованием stoul заключается в том, что если я ввожу 100 ( 101, это не работает, поэтому следует фиксированному коду, но не должен использоваться. Как предложил Ламанди, вместо этого используйте std::stringstream.

std::size_t stringPosition = 0;
std::size_t stringPositionSum = 0;
for( ; stringPosition < console_buffer.length() && integersNumberOf < 1024; ){
    try{
        integersFound[integersNumberOf] = std::stoul(&console_buffer[stringPositionSum], &stringPosition, 10);
        integersNumberOf++;
        stringPositionSum = stringPositionSum + stringPosition;
    }
    catch(std::exception& exception){
        break;
    } //This catch will be used constantly by this buggy code.

person Mateus Matucuma Teixeira    schedule 11.12.2017    source источник
comment
Есть ли смысл во всех указателях? Но вы передаете std::string по значению.   -  person DeiDei    schedule 11.12.2017
comment
Я пробовал пройти по указателю, это тоже не сработало. Указатели: integersNumberOf_Update предназначен для изменения значения непосредственно в console(), как это делает stoul для параметра size_t. integersFound должен распределяться динамически, так как количество целых чисел может быть очень большим. integersConverted просто получает указатель на integersFound .   -  person Mateus Matucuma Teixeira    schedule 11.12.2017


Ответы (2)


for( ; stringPosition < console_buffer.length() && integersNumberOf < 1024; ){
        integersFound[integersNumberOf] = std::stoul(console_buffer, &stringPosition, 10); //10 = Decimal
        integersNumberOf++;
    }

не делает то, что вы хотите.

Вы снова и снова передаете одну и ту же строку std::stoul. Ваша функция std::stoul продолжает считывать первое число каждый раз. Когда у вас было только одно число, stringPosition < console_buffer.length() приводило к остановке цикла. Если у вас более одного номера, stringPosition никогда не превысит console_buffer.length().

Второй параметр std::stoul не указывает, откуда в строке начинать чтение; это дает вам количество обработанных символов.

Для задачи, с которой вы сталкиваетесь, вам нужен stringstream.

#include <iostream>
#include <sstream>
#include <array>

int main ()
{
     std::istringstream console_buffer("123 345 3 5 2 3 4 5 6 7 7  232 34 332 234 55");

     std::array<unsigned long, 1024> integerArray;
     size_t count = 0;
     while(console_buffer && count < integerArray.size())
         console_buffer >> integerArray[count++];

     for(int i = 0; i < count; i++)
         std::cout<<integerArray[i] << ' ';
     return 0;
}
person Yashas    schedule 11.12.2017
comment
О Боже! Я пытаюсь исправить код уже почти 2 часа, так как ваши ответы очень важны, я исправил код с помощью try-catch; он все еще очень нестабилен, так как stoul действительно не делает то, что мне нужно, и я не понял его параметр, так как впервые использую его. Основной пост будет обновляться с исправленным кодом, но нигде не будет использоваться. - person Mateus Matucuma Teixeira; 11.12.2017
comment
Вы должны использовать строковые потоки. Они работают как cin и cout. Разница в том, что строковые потоки работают со строкой, тогда как ваши cin и cout работают с stdin и stdout. Также рассмотрите возможность использования typedef для unsigned long. - person Yashas; 11.12.2017
comment
Приложение: Недавно добавленный std::size избавит от необходимости... Что ж. Вы сделали эту похвалу бессмысленной, не так ли? - person user4581301; 11.12.2017
comment
@ user4581301 Я не знал об этом. Спасибо. В любом случае я заменил массив C-стиля на std::array. - person Yashas; 11.12.2017
comment
std::array это правильный путь. Единственным лучшим решением может быть std::vector. Тем не менее, нужно увидеть больше вариантов использования Аскера, чтобы быть уверенным. - person user4581301; 11.12.2017

Рассмотрите возможность использования std::vector и std::stringstream, чтобы облегчить себе работу.

std::vector<unsigned long int> StringToIntegerVector(const std::string& input)
{
    std::istringstream iss(input);
    unsigned long int temp;
    std::vector<unsigned long int> results;
    while (iss >> temp)
        results.push_back(temp);
    return results;
}
person lamandy    schedule 11.12.2017
comment
Большое спасибо за образец кода! Я буду сейчас, намного меньше, чем мой коренастый код. - person Mateus Matucuma Teixeira; 11.12.2017