У меня есть функция, возвращающая двоичное представление байта:
std::string ToBinary(unsigned char &Num)
{
char str[8];
char Symb = 0;
int i = 0;
while (i<8)
{
_asm
{
//push al
shr byte[Num], 1
mov al, 0
adc al, 30h
mov byte[Symb], al
//pop al
}
str[7-i] = Symb;
i++;
}
return std::string(str);
}
И это зов:
std::string BinOut = ToBinary(ByteValue);
Проблема в том, что вместо строки из 8 символов он возвращает строку из 14 символов. Очевидно, что внутри функции str показывает правильное значение. Как сделать так, чтобы он возвращал 8 символов?
return std::string(str, 8); См. (4) в: en.cppreference.com/w/cpp/string/basic_string/basic_string Не требует завершения NULL и допускает встроенные NULL.
str не имеет нулевого конца, поэтому у вас есть UB
Silly mistake: forgot about null terminator Это ответ? Если да, пожалуйста, не помещайте это в свой вопрос. Вместо этого проголосуйте за некоторые ответы, в которых указана ошибка, и примите ее, если вас устраивает ответ.





Проблема вызвана тем, что ваш символьный массив не содержит завершающего нулевого символа. Одно из решений - выделить массив с одним дополнительным символом, чтобы вы могли завершить его нулевым значением:
char str[9]
//...
str[8] = '\0'
В качестве альтернативы вы можете использовать перегруженный конструктор строк, который позволяет вам передать параметр для количества используемых символов из входного массива:
std :: string (str, 8);
Это перебор. Просто используйте другую перегрузку std::string. Это также не будет работать должным образом в общем случае (где в последовательности БУДЕТ нулевой байт!)
@SergeyA Да, я предполагаю, что предыдущий код правильно строит массив из 8 ненулевых символов.
Конструктор std::string, который принимает указатель на char, требует, чтобы указанная строка оканчивалась нулем. Ваш str не имеет нулевого конца, поэтому поведение программы не определено.
Вы также можете
char[9] и установите последний символ на '\0'. Это работает только в том случае, если str не содержит нулевых байтов, поскольку первый из них будет терминатором.std::string(char *s, std::size_t count), у которого нет такого требования.Вы также можете сохранить char str[8];, а затем использовать return {std::begin(str), std::end(str)}; для инициализации возвращаемой строки.
Прочтите ericlippert.com/2014/03/05/how-to-debug-small-programs для получения советов по отладке вашего кода.