Последнее значение массива символов неизвестно - 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 символов), и затем, когда вы обнуляете массив, помещая в него нули для заполнения, вы должны получить ожидаемый результат.