我调用从套接字接收数据的 recv() 并通过十六进制打印缓冲区内容的结尾
char nbuff[BUFSZ];
while ((r_n=recv(sfd,rbuff,B_BUF,MSG_EOF))>-1)
{
printf("r_n:%d eob_p:%x\n",r_n,rbuff[r_n-1]);
if (r_n==0)
{
break;
}
memset(rbuff,0,B_BUF);
}
结果是
r_n:1674 eob_p:3c
r_n:1228 eob_p:76
r_n:2456 eob_p:ffffff81
r_n:1228 eob_p:4b
r_n:1228 eob_p:49
r_n:2456 eob_p:57
r_n:1417 eob_p:ffffff82
我很困惑为什么结果是 4 个字节。我创建了另一个代码来打印从 buff 保存的文件
int main ()
{
char buff[11686];
memset(buff,0,11686);
FILE *in =fopen("web/www.sse.com.cn.html","r");
fread(buff,11686,1,in);
for (int i = 0; i < 11686 ; i++)
{
printf("%x\n",buff[i]);
}
}
结果是
....
buff[11684]:60
buff[11685]:ffffff82
为什么 char buff 的内容大小是 4 字节buff[11685]:ffffff82
在第二个示例中,buff
是一个char
缓冲区,plainchar
是您机器上的有符号类型,并且您在 中存储负值buff
,因此当它们int
在调用中转换为时printf()
,它们是负整数(小幅度) , 以十六进制打印。
实际上,链接是指向 C11 的在线草案,而不是 C18,在 HTML 中,它允许链接到标准中的相关段落。AFAIK,无论如何,这些细节在 C90、C99、C11 和 C18 之间并没有改变。
标准说普通char
类型等效于signed char
or 或unsigned char
。
这三种类型
char
,signed char
以及unsigned char
统称为字符类型。实现应定义char
为具有相同的范围,表示和行为如任一signed char
或unsigned char
。45)45)
CHAR_MIN
,在 中定义<limits.h>
,将具有值 0 或 之一SCHAR_MIN
,这可用于区分这两个选项。无论做出char
何种选择,它都是与其他两个不同的类型,并且与任何一个都不兼容。
2 表达式中可以使用 int 或 unsigned int 的地方可以使用以下内容:
- 具有整数类型(除了
int
orunsigned int
)的对象或表达式,其整数转换等级小于或等于int
and的等级unsigned int
。_Bool
,int
,signed int
, 或类型的位域unsigned int
。如果 an
int
可以表示原始类型的所有值(受宽度限制,对于位域),则将该值转换为int
; 否则,它被转换为unsigned int
。这些称为整数促销。58)所有其他类型都不受整数提升的影响。3 整数提升保留值,包括符号。如前所述,是否将“普通”
char
视为有符号是实现定义的。58)的整数优惠只应用:如通常的算术转换的一部分,某些参数表达式,以一元的操作数
+
,-
以及~
运营商和所述移位运算符的两个操作数,如由它们各自的子类指定。
6 如果表示被调用函数的表达式的类型不包含原型,则对每个参数执行整数提升,并将具有类型的参数
float
提升为double
。这些称为默认参数提升。如果参数数量不等于参数数量,则行为未定义。如果函数定义的类型包含原型,并且原型以省略号 (, ...
) 或提升后的参数类型与参数类型不兼容,行为未定义。如果函数定义的类型不包含原型,并且提升后的参数类型与提升后的参数类型不兼容,则行为未定义,但以下情况除外:
- 一个提升类型是有符号整数类型,另一个提升类型是对应的无符号整数类型,值在两种类型中都可以表示;
- 这两种类型都是指向字符类型或 void 的限定或非限定版本的指针。
7 如果表示被调用函数的表达式的类型确实包含原型,则参数将像通过赋值一样隐式转换为相应参数的类型,将每个参数的类型视为其非限定版本声明的类型。函数原型声明符中的省略号表示在最后一个声明的参数之后停止参数类型转换。默认参数提升是在尾随参数上执行的。
注意第 6.5.2.6 节¶7 的最后两句——当char
值被“整数提升”提升时,它们被提升为 a (signed) int
,负值保持为负。由于 anint
有 4 个字节,并且您可能拥有的所有机器都使用二进制补码算法,因此该值的最重要的 3 个字节将为每个 0xFF。
到总是打印2位十六进制的字符,使用%.2X
(或者%.2x
如果你喜欢;也可以使用任一%02X
或%02x
),并通过任一(unsigned char)rbuff[r_n-1]
或rbuff[r_n-1] & 0xFF
作为参数(使用从第一示例中的变量)。或者,使用第二个示例中的变量:
printf("%.2X\n", (unsigned char)buff[i]);
printf("%.2X\n", buff[i] & 0xFF);
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句