Последнее значение массива символов неизвестно - C

Я делаю простую программу на C, которая проверяет длину некоторого массива char, и если он меньше 8, я хочу заполнить новый массив нулями и добавить его в прежний массив. Здесь возникает проблема. Я не знаю, почему последние значения являются некоторыми признаками (см. Фото).

char* hexadecimalno = decToHex(decimal,hexadecimal);
printf("Hexadecimal: %s\n", hexadecimalno);
char zeroes [8 - strlen(hexadecimalno)];
if(strlen(hexadecimalno) < 8){
    for(i = 0; i < (8-strlen(hexadecimalno)); i++){
        zeroes[i]='0';
    }
}
printf("zeroes: %s\n",zeroes);
strcat(zeroes,hexadecimalno);
printf("zeroes: %s\n",zeroes);

результат

1 ответ

Решение

В C строки (которые, как вы знаете, являются массивами символов) не имеют специальных метаданных, которые сообщают вам их длину. Вместо этого соглашение состоит в том, что строка останавливается на первом символе, char значение 0, Это называется "нулевым окончанием". Способ инициализации вашего кода zeroes не ставит нулевой символ в конец массива. (Не путайте '0' символы, которые вы вводите с NUL-символами - они имеют char значение 48 не 0.)

Все функции манипуляции со строками принимают это соглашение, поэтому при вызове strcat ищет это 0 символ для определения точки, с которой начинается добавление шестнадцатеричных значений.

C также не выделяет память автоматически. Предполагается, что вы точно знаете, что делаете. Итак, ваш код использует функцию C99 для динамического выделения массива zeroes который имеет ровно столько элементов, сколько вам нужно '0' символы добавлены. Вы не выделяете дополнительный байт для завершающего символа NUL, и strcat также предполагается, что вы выделили место для содержимого hexadecimalno, которого у вас нет. В C это не вызывает ошибку проверки границ. Он просто перезаписывает память, которую вы не должны переписывать. Таким образом, вы должны быть очень осторожны, чтобы выделять достаточно памяти и записывать только ту память, которую вы на самом деле выделили.

В этом случае вы хотите hexadecimalno всегда иметь длину 8 цифр, оставляя слева нули. Это означает, что вам нужен массив с 8 char значения, плюс один для терминатора NUL. Так, zeroes должен быть char[9],

После вашего цикла, который устанавливает zeroes[i] = '0' для правильного числа нулей, вам нужно установить следующий элемент в char значение 0, Тот факт, что вы набираете ноль, сбивает с толку вещи, но, опять же, помните, что '0' а также 0 это две разные вещи.

При условии, что вы выделяете достаточно места (не менее 9 символов, при условии, что hexadecimalno никогда не будет длиннее, чем 8 символов), и затем, когда вы обнуляете массив, помещая в него нули для заполнения, вы должны получить ожидаемый результат.

Другие вопросы по тегам