неподписанные символы и sprintf () C - PullRequest
0 голосов
/ 10 января 2019

У меня есть этот код:

int main(){

char buffer[1024];
char port = 1;
int length = 255;
char * record = "$TAG ,0 ,89 ,0, 1\n";

if(length < 0 || length > 255){
    printf("Error - length out of range for an unsigned char.\n");
    exit(1);
}

snprintf(buffer, 1024, "%c%c%s", port, (unsigned char) length, record);

int port_rc     = buffer[0];
int length_rc   = buffer[1]; 

printf("port_rc: %d\n",port_rc);
printf("length_rc: %d\n",length_rc);

return 0;

}

Вывод при запуске:

port_rc: 1 length_rc: -1

Я думаю, что мне здесь чего-то не хватает в терминах snprintf (), поскольку я не вижу значения 255 при чтении созданного им массива. Я предполагаю, что snprintf () продвигает переменную length до int или чего-то еще. Кто-нибудь знает, как мне этого добиться?

Спасибо.

Ответы [ 3 ]

0 голосов
/ 10 января 2019

РАБОЧЕЕ РЕШЕНИЕ:

int main(){

unsigned char buffer[1024];
char port = 1;
int length = 255;
char * record = "$TAG ,0 ,89 ,0, 1\n";

if(length < 0 || length > 255){
    printf("Error - length out of range for an unsigned char.\n");
    exit(1);
}

buffer[0] = port;
buffer[1] = length;
snprintf((char *)(buffer), sizeof buffer - 2, "%c%c%s", port,length,record);

int port_rc     = buffer[0];
int length_rc   = buffer[1]; 
char char_first = buffer[2];

printf("port_rc: %d\n",port_rc);
printf("length_rc: %d\n",length_rc);
printf("char_first: %c\n",char_first);


return 0;

}

ВОЗВРАТ:

port_rc: 1 length_rc: 255 char_first: $

0 голосов
/ 10 января 2019

«Будьте осторожны», при оценке такого «решения».

По моему скромному вопросу, коренная проблема - в вашем первоначальном посте - состоит в том, что переменные port_rc и length_rc должны были быть объявлены как целые числа без знака . Вы не хотите, чтобы значение, такое как $FF, было ошибочно «расширенным знаком», чтобы стать $FFFFFFFF == -1 ...

Ваше «решение» сильно отличается от оригинала, поскольку, как вы видите, оно теперь сохраняет в и buffer[0] и buffer[1] перед тем, как затем извлекать и проверять эти значения!

0 голосов
/ 10 января 2019

Я не думаю, что вы можете использовать sprintf() для хранения 255 в буфере. Аргумент буфера для sprintf() является массивом char. Является ли char signed или unsigned по умолчанию, определяется реализацией; см. Является ли char подписанным или неподписанным по умолчанию? . Если 255 больше CHAR_MAX, попытка сохранить 255 приведет к неопределенному поведению; если реализация по умолчанию равна signed, тогда CHAR_MAX, вероятно, будет 127.

Я предлагаю не использовать sprintf() для сохранения чисел в буфере. Объявите это как:

unsigned char buffer[127];

Тогда вы можете сделать:

buffer[0] = port;
buffer[1] = length;
snprintf((char *)(buffer + 2), sizeof buffer - 2, "%s", record);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...