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