Code Bye

关于C语言字符串的问题

redhat6 64位环境下的C语言程序。
需要拼一个报文,服务端要求报文头是4字节长度。
void little_endian(const int data, unsigned char* addr)
{
addr[0] = data & 0xff;
addr[1] = (data & 0xff00) >> 8;
addr[2] = (data & 0xff0000) >> 16;
addr[3] = (data & 0xff000000) >> 24;
}

int main ()
{
//此处是包体
char* msg = “send data:abcdefg”;
int msglen = strlen(msg);

//声明发送变量 sendbuf
char sendBuf[2000] ;
memset(sendBuf, 0, sizeof(sendBuf));
//把长度int转换成4字节char, 再把包体加上
little_endian(msglen, &sendBuf[0]);
memcpy(&sendBuf[4], msg, msglen);
//问题在这能打印出来, sendbuf 的size只有1, 打印出来的sendBuf也只有一个字节
printf(“sendBuf size:%d\n”,strlen(sendBuf));
printf(“sendBuf:%s \n”,sendBuf);
}
用gdb跟了一下 little_endian(msglen, &sendBuf[0]) 转换后,sendBuf[0] 就够保存不太大的长度,
此时sendBuf[1], sendBuf[2], sendBuf[3], 还是初始化的那个状态,strlen(sendBuf) 判断时,只判断一个字节后,就遇到\0,认为字符串结束了。没办法和后边的msg连到一起。
除了 little_endian函数,用memcpy(&sendBuf[0], &msglen, 4)也试了一下,是一样的结果。
把上述的char都该成unsigned char也是一样结果
哪位老鸟帮忙定位下?谢谢

解决方案

15

 little_endian(msglen, &sendBuf[0]);
第二个参数类型是unsigned char *,这个函数是把一个整数(msglen)放在sendBuf缓冲区中。
sendBuf不表示一个以\0结尾的C风格字符串!
对sendBuf执行strlen(sendBuf)是错误的。strlen只能对以\0结尾的C风格字符串操作。
后面printf %s想打印出sendBuf,也是错误的。

15

    printf("sendBuf size:%d\n", 4 + strlen(&sendBuf[4]));
    printf("sendBuf:%s \n", &sendBuf[4]);
或,打印unsigned char:
int i;
for (i = 0; i < 4 + msglen; ++i) {
    printf("%02hhX ", sendBuf[i]);
}
建议:把数据包封装一下,相似:
typedef struct message_s {
    int length;
    char str[2000];
} message_t;
void message_dump(const message_t * msg) {
    printf("length=%d, str="%s"\n", msg->length, msg->str);
}
void message_fill(message_t * msg, const char * str) {
    strncpy(msg->str, str, sizeof(msg->str) - 1);
    msg->str[sizeof(msg->str) - 1] = "\0";
    msg->length = strlen(msg->str);
}

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明关于C语言字符串的问题