无符号字符和sprintf()C

无符号字符和sprintf()C,c,printf,C,Printf,我有以下代码: 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,

我有以下代码:

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;
intmain(){
字符缓冲区[1024];
字符端口=1;
整数长度=255;
char*record=“$TAG,0,89,0,1\n”;
如果(长度<0 | |长度>255){
printf(“错误-长度超出无符号字符的范围。\n”);
出口(1);
}
snprintf(缓冲区,1024,“%c%c%s”,端口,(无符号字符)长度,记录);
int port_rc=缓冲区[0];
int length_rc=缓冲区[1];
printf(“端口\u rc:%d\n”,端口\u rc);
printf(“长度\u rc:%d\n”,长度\u rc);
返回0;
}

运行时的输出:

port\u rc:1
长度_rc:-1

我想我在这里遗漏了一些关于snprintf()的内容,因为我在读取它创建的数组时没有看到255值。我猜snprintf()将变量“length”提升为int或其他形式。有人知道我怎样才能做到这一点吗


谢谢。

我认为您不能使用
sprintf()
255
存储到缓冲区中。
sprintf()
的缓冲区参数是一个
char
数组。默认情况下,
char
signed
还是
unsigned
,由实现定义;看见如果
255
大于
CHAR\u MAX
,尝试存储
255
会导致未定义的行为;如果实现默认为
signed
,则
CHAR\u MAX
可能是
127

我建议不要使用
sprintf()
将数字存储到缓冲区中。声明如下:

unsigned char buffer[127];
然后你可以做:

buffer[0] = port;
buffer[1] = length;
snprintf((char *)(buffer + 2), sizeof buffer - 2, "%s", record);
工作解决方案:

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;
intmain(){
无符号字符缓冲区[1024];
字符端口=1;
整数长度=255;
char*record=“$TAG,0,89,0,1\n”;
如果(长度<0 | |长度>255){
printf(“错误-长度超出无符号字符的范围。\n”);
出口(1);
}
缓冲区[0]=端口;
缓冲区[1]=长度;
snprintf((char*)(buffer),buffer-2的大小,“%c%c%s”,端口,长度,记录);
int port_rc=缓冲区[0];
int length_rc=缓冲区[1];
char char_first=缓冲区[2];
printf(“端口\u rc:%d\n”,端口\u rc);
printf(“长度\u rc:%d\n”,长度\u rc);
printf(“字符优先:%c\n”,字符优先);
返回0;
}

返回:

port\u rc:1
长度:255
首先:$

“不过,在判断这样的“解决方案”时要小心。”

在我看来,在你最初的帖子中,根本问题是变量
port\u rc
length\u rc
应该声明为无符号整数。您不希望像
$FF
这样的值被错误地“符号扩展”为
$ffffff===-1


您的“解决方案”与原来的完全不同,因为正如您所看到的,它现在存储在
缓冲区[0]
缓冲区[1]
中,然后再检索和检查这些值

“255”
的第一个字符是
'2'
,它的值是ascii格式的
50
。@tkausl什么使你不能回答?你会使用不同的格式说明符得到
255
字符
假定为有符号,因为您使用的是
(无符号字符)
强制转换,而不是
(字符)
。所以你会得到
-1
buffer[1]
的类型是
char
,它实际上不可能存储255个字符(假设你的系统有签名的纯char)@M.M-是的,这就是为什么我尝试使用usigned char。我已经算出了,你可以在我的答案中看到我的解决方案。对,但这样做不会在变量“length_rc”中返回255。请参阅上面修改的代码。如果我把“长度”改为127(最大的有符号字符数),输出就会如预期的那样产生。缓冲区是
char[]
,而不是
unsigned char[]
。所以
缓冲区[1]
被签名。将
255
存储到缓冲区会导致未定义的行为。我已更新了答案,以说明如何更安全地执行此操作。非常感谢@Bamar-我已将您的解决方案合并到了一起。我的帖子已更新,以反映工作变化。你应该将工作解决方案放在答案中,而不是问题中。我同意,但我确实确保有效返回值为0-255以确保。