std::string 在整数数组上使用 stoul 时输出错误

Wrong output with std::string using stoul, on integer array

嗨,我在尝试将一行数字(例如: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',等等;不幸的是没有工作..

UPDATE --- 主题首次发布后 5 分钟; 正如 Yashas 回答的那样,问题是在 console_defaultSyntaxProcessing for 循环; stoul &stringPosition returns 读取的字符数,而不是 std::string 的位置。 使用 stoul 的另一个问题是,如果我输入 100 ( 101,它不起作用,所以遵循固定代码但不得使用。 正如 lamandy 建议的那样,请改用 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.
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;
}

考虑使用 std::vectorstd::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;
}