2017-02-09 158 views
2

我正从套接字接收一些数据。
之后,我想打印接收到的字符数组中的单个字节。将字符串转换为字符后打印单字节

下面是我使用的代码:

char buf[100];                 
int i = 0;                  
while (1)                  
{                    
    rc = recv(socket_fd, buf, sizeof(buf), 0);         

    if (rc > 0)                 
    {                   
     printf("Pos1 = %x.\n", (char)buf[17]); 
     printf("Pos2 = %x.\n", (char)buf[22]); 
    }  
} 

但这打印出4个字节。如果我将字符转换为无符号字符,则打印单字节。那么这两个类型转换之间的区别是什么,导致打印的字节数不同。

输出:

Pos1 = 1 

Pos2 = ffffff83 
+0

为什么使用'%x'?你需要十六进制值吗? – Jarvis

+0

是的。我希望以十六进制打印该值。 –

+0

分享您的输出。你是如何确定它正在打印4个字节的? –

回答

1

如果你想打印只需2个半字节,使用:

printf("Pos1 = %02x.\n", (unsigned)(unsigned char)buf[17]); 
/*    ^^       */ 
/* Print 2 nibbles with 0 prefix if required */ 

在某些系统中,char可以表现为signed char,你会看到ff前缀以示负数。因此,您必须在此类系统上投射您的buf[i]unsigned char。第二个无符号的使用,如果你去了printf的

说明符“X”打印无符号的十六进制整数的C STDIO LIB参考与符%x

Working example

+0

我试过了,但结果是一样的。它也打印4个字节。 –

+0

对不起,我盲目地复制了铸件。确保你投射到'unsigned char'。 –

+0

是的。它正在与ffffff相提并论。我的输出就像Pos2 = ffffff83。 –

1

匹配参数的类型。

所以首先,打印功能将会期望一个整数值。

在你的例子中,你正在转换为签名字符。

看上去发生了什么,是将变量转换为带符号字符,如果该值超过127(0X7F),则设置的有符号位将扩展为4字节整数实体。另一方面,如果值为正值(0到127),则输出(虽然在技术上是一个无符号整型值)将与无符号字符型转换相同。

例如,如果您将Char(作为char 转换为Char)以及将其转换为无符号字符时转换为80,则128(0x80)将显示为FFFFFF80。

127另一方面将显示为7F与任一演员。

因此,使用printf时,要打印的变量类型应该与说明符类型匹配。

1

那么这两个类型转换之间有什么区别,即导致不同数量的字节?

传递给函数printf的每个输入参数在被推入堆栈之前都被“扩展”为4或8个字节(取决于类型)。

当您传递类型为signed的输入参数时,符号位将“保留”。例如,signed char 0x89扩展为signed int 0xFFFFFF89

虽然unsigned char 0x89扩展到unsigned int 0x00000089


请注意,上面的答案是平台相关的。

我假设你的平台上:

  • CHAR_BIT是8
  • sizeof int是4
  • sizeof double是8

AFAIK至于printf输入参数:

  • 一个整型参数比int小扩展到int
  • 非整参数比double小扩展到double
0

告诉printf要传递在unsigned int的一半的一半做

printf("Pos1 = %hhx.\n", (unsigned char) buf[17]);