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::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;
}
嗨,我在尝试将一行数字(例如: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::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;
}