Я пытаюсь преобразовать std :: string, содержащий несколько значений, разделенных пробелами, в векторный объект. У меня это работает (имеется в виду, что отладчик показывает правильные значения в векторе в конце алгоритма), однако я получаю исключение, которое никогда раньше не видел. Исключение ниже:
Я никогда не видел этого раньше, и я целый час изучал, что вызывает это, и я до сих пор не понимаю этого.
Мой алгоритм, который вызывает исключение, выглядит следующим образом:
vector<BYTE> ConvertStringOfValuesToVectorOfBytes(std::string valStr)
{
vector<string> vectorOfValues = split(valStr, ' '); //split string into vector of strings (works)
vector<BYTE> Hex;
vector<const char*> vectOfCStrings;
for(int i = 0; i < vectorOfValues.size(); i++)
{
const char* temp = vectorOfValues[i].c_str();
vectOfCStrings.push_back(temp);
}
//now we have a vector of c strings...
for(int i = 0; i < vectOfCStrings.size(); i++)
{
char temp = 0;
sscanf(vectOfCStrings[i], "%x", &temp);
Hex.push_back(temp);
}
return Hex;
} //<-- debugger gets to here and on the next step causes the exception
Я понятия не имею, как я могу решить эту проблему. Как я уже сказал, алгоритм «работает» в том смысле, что я получаю правильный результат, мне просто нужно устранить исключение. Как это исправить?
Эта строка не верна:
sscanf(vectOfCStrings[i], "%x", &temp);
Формат %x
должен быть предназначен для использования для int
не char
,
Вы получаете повреждение стека, потому что sscanf
ожидает адрес int
, Он пытается использовать адрес, который вы передаете как способный удерживать int
, Очевидно, он использует больше памяти, чем допустимо.
Что вам нужно это:
for(int i = 0; i < vectOfCStrings.size(); i++)
{
int temp = 0;
sscanf(vectOfCStrings[i], "%x", &temp);
Hex.push_back(static_cast<char>(temp));
}
std::vector<unsigned char> func(std::string valStr) {
vector<string> vectorOfValues = split(valStr); //split string into vector of strings (works)
vector<BYTE> Hex;
vector<const char*> vectOfCStrings;
for(int i = 0; i < vectorOfValues.size(); i++) {
const char* temp = vectorOfValues[i].c_str();
vectOfCStrings.push_back(temp);
}
//now we have a vector of c strings...
for(int i = 0; i < vectOfCStrings.size(); i++) {
int temp = 0;
sscanf(vectOfCStrings[i], "%x", &temp);
Hex.push_back(char(temp));
}
return Hex;
}
Так что да, я только что сделал второй tmp
Int, потому что sscanf
и тому подобное int
как типы, а так как byte
меньше, чем int, что вызывает переполнение.
Не уверен, что это работает, но это больше не дает мне ошибку.
Culprit, кажется, в этих двух строках:
char temp = 0;
sscanf(vectOfCStrings[i], "%x", &temp);
Именно поэтому семейство функций printf / scanf не используется в C ++ и заменено на std::iostream
механизм. функция sscanf
ожидает получить указатель на unsigned int, когда вы укажете %x
но вы передаете указатель на символ, и нет никакого способа sscanf
Сам может подтвердить это. Хотя некоторые современные компиляторы могут проверять, переданы ли значения в printf
или же scanf
сопоставляет спецификаторы формата и генерирует предупреждения в противном случае, что в общем случае не работает (например, формат передается функции вместо использования строкового литерала). Так вот sscanf
указатель разыменования &Temp как указатель на unsigned int
и перезаписывает память вокруг временной переменной как sizeof char == 1.
Что именно ваш алгоритм пытается достичь?
Судя по всему, вы разбиваете std :: string на std :: vector из ‘words’, а затем конвертируете эти слова в строки в стиле c (почему?), Затем собираете std: vector, содержащий первую букву каждого слова, интерпретируемого как int. Вместо этого используйте std: stringstream:
for ( auto& word : vectorOfValues )
{
for ( auto& letter : word )
{
unsigned int val;
std::stringstream ss;
ss << std::hex << word[0];
ss >> val;
Hex.push_back( static_cast<BYTE>( val ) );
}
}
Как правило, если вы не взаимодействуете напрямую с C API, вам не следует использовать строки в стиле c в c ++.