Спецификатор формата для короткого целого числа

StackOverflow https://stackoverflow.com/questions/2952631

Вопрос

Я неправильно использую спецификаторы формата в 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 shortS может заняться до 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); 

Но это не имеет смысла для человека, глядя на это, и чувствителен к эндзиазности. Я настоятельно рекомендую против этого.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top