Спецификатор формата для короткого целого числа
-
22-10-2019 - |
Вопрос
Я неправильно использую спецификаторы формата в C. Несколько строк кода:
int main()
{
char dest[]="stack";
unsigned short val = 500;
char c = 'a';
char* final = (char*) malloc(strlen(dest) + 6);
snprintf(final, strlen(dest)+6, "%c%c%hd%c%c%s", c, c, val, c, c, dest);
printf("%s\n", final);
return 0;
}
Я хочу скопировать в
окончательный [0] = случайный финал [1] = случайный финал [2] и окончательный [3] = финал короткого массива [4] = еще один чар ....
Моя проблема в том, что я хочу скопировать два байта коротких до 2 байтов окончательного массива.
Спасибо.
Решение
Я в замешательстве - проблема в том, что вы говорите strlen(dest)+6
который ограничивает длину final
строка до 10 chars (плюс нулевый терминатор). Если вы говорите strlen(dest)+8
Тогда будет достаточно места для полной струны.
Обновлять
Несмотря на то, что короткий размер может составлять всего 2 байта, когда он напечатан как струна, каждый символ займет байт. Таким образом, это означает, что это может потребовать до 5 байтов места, чтобы написать короткую строку, если вы пишете число выше 10000.
Теперь, если вы напишете короткую строку как шестнадцатеричный номер, используя %x
Спецификатор формата, он займет не более 2 байтов.
Другие советы
Вам нужно выделить место для 13 символов, а не 11. Не забывайте о прекращении NULL.
При отформатировании число (500) занимает три места, а не одно. Так что ваши snsprintf
должен дать окончательную длину как strlen(dest)+5+3
. Анкет Тогда также исправьте свой malloc
позвонить, чтобы настроить. Если вы хотите вычислить strlen
Из этого номера сделайте это с таким вызовом strlen(itoa(val))
. Анкет Кроме того, не могу забыть NULL в конце DEST, но я думаю, что Стрлен принимает это во внимание, но я не точно.
Простой ответ - вы только выделили достаточно места для символов Strlen (dest) + 6, когда во всей реальности, похоже, у вас будет 8 дополнительных символов ... поскольку у вас есть 2 Chars + 3 chars в вашем номере + 2 chars после + dest (5 chars) = 13 char, когда вы выделили 11 Chars.
Unsigned short
S может заняться до 5 символов, верно? (0 - 65535)
Похоже, вам нужно выделить 5 символов для вашего unsigned short
Чтобы покрыть все значения.
Что указывает на использование этого:
char* final = (char*) malloc(strlen(dest) + 10);
Вы теряете один байт, потому что вы думаете, что короткая переменная занимает 2 байта. Но это требует три: один для каждого цифрового символа ('5', '0', '0'). Также вам нужен '\0'
Терминатор (+1 байт).
==> вам нужно strlen(dest) + 8
Используйте 8 вместо 6 на:
char* final = (char*) malloc(strlen(dest) + 6);
а также
snprintf(final, strlen(dest)+6, "%c%c%hd%c%c%s", c, c, val, c, c, dest);
Похоже, что основное недопонимание заключается в том, что «2-байтовая» короткая не может быть представлен на экране как 2 1-байтовых символа.
Сначала оставьте достаточно места:
char* final = (char*) malloc(strlen(dest) + 9);
Весь диапазон возможных значений для 1-байтового символа не доступен для печати. Если вы хотите отобразить это на экране и быть читаемым, вам придется кодировать 2-байтовые короткие как 4 шестнадцатеричных байтов, например:
## as hex, 4 characters
snprintf(final, sizeof(final), "%c%c%4x%c%c%s", c, c, val, c, c, dest);
Если вы пишете это в файл, это нормально, и вы можете попробовать следующее:
## print raw bytes, upper byte, then lower byte.
snprintf(final, sizeof(final), "%c%c%c%c%c%c%s", c, c, ((val<<8)&0xFF), ((val>>8)&0xFF), c, c, dest);
Но это не имеет смысла для человека, глядя на это, и чувствителен к эндзиазности. Я настоятельно рекомендую против этого.