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

时间:2017-12-11 02:52:15

标签: c++ string getline size-t

嗨,我在尝试将一行数字(例如: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分钟; 正如Yashas回答的那样,问题是在console_defaultSyntaxProcessing for循环中; stoul&amp; stringPosition返回读取的字符数,而不是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.

2 个答案:

答案 0 :(得分:1)

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;
}

答案 1 :(得分:1)

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