user-0 提问: 关于数组清零后再输出的问题

回复:
user: user-0
content: 引用 16 楼 zhao4zhong1 的回复:我的意思是你要小心结构体字节对齐问题。 我在网上找了很多程序，好像大家都没有涉及结构体字节对齐问题。直接用memcpy（）把一个数组拷贝到一个结构体中的，但是我这么做发现拷贝到结构体中的数据是错的，现在在研究结构体字节的对齐方式

user: user-1
content: 参考printf的源代码C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\output.c

user: user-1
content: “多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，搬手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

user: user-2
content: 引用 7 楼 xue_opnet 的回复:[quote=引用 4 楼 cyfcsd 的回复:] 程序片段看不懂啊，你能不能把整个程序发出来啊  程序涉及的太多，贴的程序越多。越乱。 贴出来的程序的功能就是socket通信，客户端发一个数组给服务端，服务端收到数组后打印出数组中的内容，接着再把数组转换成结构体，再打印出结构体中的内容。[/quote] 那问题是出在哪儿了啊，看不懂啊，你要自己学会调试，关键弄明白数据是怎么传的，然后找个地方打断点看看是不是正确的，要是不行就直接输出，这样逐步确定出错地方 比如说发送消息之前看看传进去的实参，进入函数后看看传进来的形参，转换之后看看转换之后的结果，返回前看看返回的参数，返回后看看返回的结果。。。 再厉害的大神也是这么调试的，那些一眼就看出错误的人都是以前犯过同样的错误！

user: user-1
content: 我的意思是你要小心结构体字节对齐问题。

user: user-3
content: 6楼的回答。。。。 sizeof的是数组名，又不是指针名，怎么会是4呢

user: user-0
content: 引用 4 楼 cyfcsd 的回复:程序片段看不懂啊，你能不能把整个程序发出来啊  程序涉及的太多，贴的程序越多。越乱。 贴出来的程序的功能就是socket通信，客户端发一个数组给服务端，服务端收到数组后打印出数组中的内容，接着再把数组转换成结构体，再打印出结构体中的内容。

user: user-4
content: memset(Send_Buf,0,sizeof(Send_Buf)+1);  你这个memset是有问题的，应该是memset(Send_Buf,0,20*sizeof(char));  ，你的那个Send_buf只是数组的首地址的指针而已，顶多开辟4个字节的空间， 再加1也就5个字节。

user: user-5
content: 清空了就是什么都没有了呗

user: user-2
content: 程序片段看不懂啊，你能不能把整个程序发出来啊

user: user-0
content: 引用 14 楼 zhao4zhong1 的回复:玄  参考下面：#include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 // //A1.a 0 //A1.b 4 //A1.c 17 // //A2.a 0 //A2.b 4 //A2.c 18 // //A4.a 0 //A4.b 4 //A4.c 20 // //A8.a 0 //A8.b 4 //A8.c 24 // //A16.a 0 //A16.b 4 //A16.c 24 // //  没有看出来哪里是数组中的数据转换到结构体中。 #define field_offset(s,f) (int)(&(((struct s *)(0))->f))这条语句是定义了一个结构体中数据的位置 #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; 这是定义了几个结构体 组函数用来把结构体中的内容输出，在哪里给结构体赋值的呢？

user: user-1
content: 玄  参考下面：#include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 // //A1.a 0 //A1.b 4 //A1.c 17 // //A2.a 0 //A2.b 4 //A2.c 18 // //A4.a 0 //A4.b 4 //A4.c 20 // //A8.a 0 //A8.b 4 //A8.c 24 // //A16.a 0 //A16.b 4 //A16.c 24 // //

user: user-0
content: 引用 9 楼 cyfcsd 的回复:[quote=引用 7 楼 xue_opnet 的回复:] [quote=引用 4 楼 cyfcsd 的回复:] 程序片段看不懂啊，你能不能把整个程序发出来啊  程序涉及的太多，贴的程序越多。越乱。 贴出来的程序的功能就是socket通信，客户端发一个数组给服务端，服务端收到数组后打印出数组中的内容，接着再把数组转换成结构体，再打印出结构体中的内容。[/quote] 那问题是出在哪儿了啊，看不懂啊，你要自己学会调试，关键弄明白数据是怎么传的，然后找个地方打断点看看是不是正确的，要是不行就直接输出，这样逐步确定出错地方 比如说发送消息之前看看传进去的实参，进入函数后看看传进来的形参，转换之后看看转换之后的结果，返回前看看返回的参数，返回后看看返回的结果。。。 再厉害的大神也是这么调试的，那些一眼就看出错误的人都是以前犯过同样的错误！[/quote] 嗯嗯，谢谢指导

user: user-0
content: 引用 11 楼 zhao4zhong1 的回复:参考printf的源代码C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\output.c 请问，如果把一个数组里的内容转换到结构体中，用下面的语句实现，正确吗？                struct Gate clt;  		memset(Recv_Buf,0,sizeof(Recv_Buf)); 		ret=recv(sClinetSock,Recv_Buf,sizeof(Recv_Buf),0); 		printf("Recv_Buf Mesg:%s\n",Recv_Buf); 		memset(&clt,0,sizeof(info)); 		memcpy(&clt,Recv_Buf,sizeof(clt));

user: user-0
content: 引用 1 楼 cyfcsd 的回复:那个memset里面不用+1吧，就是20个字节清0啊，没有21个字节  你用%s的格式输出，默认是遇到‘\0’就停止的，而‘\0’对应的ASCII码就是0，所以一遇到Send_Buf[0]就停止了，因为这里面放的就是0  谢谢，这个问题解决了，但是我遇到了下面的问题。socket通信。客户端发送语句为： send(sClntSock,Send_Buf,sizeof(Send_Buf),0); 发送的消息为：  服务端程序功能是接收到数组后再转换为结构体，程序为：                int ret;                info = (Gate *)calloc(1, sizeof(Gate));                memset(Recv_Buf,0,sizeof(Recv_Buf)+1); 		ret=recv(sClinetSock,Recv_Buf,sizeof(Recv_Buf),0); 		printf("Recv_Buf Mesg:%s",Recv_Buf); 		struct Gate Gate; 		memset(info,0,sizeof(Gate)); 		memcpy(info,Recv_Buf,sizeof(Gate));                 printf("Packet Report: \nOPNET Time = %f\ntx_wave = %d\n gate_length = %d\n gate_length1 = %f\ngate_length2 = %f\n", info->start_time,info->tx_wave,info-> gate_length,info-> gate_length1,info-> gate_length2); 结构体内容为： typedef struct Gate 	{ int tx_wave; 	int gate_length; 	int gate_length1; 	int gate_length2; 	double start_time; 	    }Gate; 结果输出的内容为：  请问这又是为什么呢?

user: user-3
content: memset(Send_Buf,0,sizeof(Send_Buf));不用加1的 memset是按字节赋值，Send_Buf[0]被赋值成了0000 0000，Send_Buf[1]被赋值成了0000 0000........... 0000 0000即ASCII码为0，即'\0' 如楼上所说用%s的格式输出，默认是遇到‘\0’就停止的

user: user-2
content: 那个memset里面不用+1吧，就是20个字节清0啊，没有21个字节  你用%s的格式输出，默认是遇到‘\0’就停止的，而‘\0’对应的ASCII码就是0，所以一遇到Send_Buf[0]就停止了，因为这里面放的就是0