我给了一个程序的shell,并且必须填写一些函数。
我有两个结构,我自动创建并传递给我必须定义的函数。
typedef struct {
char data[20];
} msg;
typedef struct {
int seqnum;
int acknum;
int checksum;
char payload[20];
} pkt;
假设我必须定义此函数foo
并已创建它:
void foo(msg message) {
printf("%s\n", message.data);
}
调用该函数时,会打印出ddddddddddddddddddddôÑ@<úHn½*Ìå«*¤ú¤F«*
。除非我不正确,否则它不应该只能容纳20个字符?我实际上并没有创建msg
。
如果我将msg.data
复制到pkt.payload
,那就更奇怪了。
void foo(msg message) {
pkt packet;
strncpy(packet.payload, message.data, sizeof(packet.payload));
printf("%s\n", message.data);
printf("%s\n", packet.payload);
}
message.data打印出与以前相同的内容,但packet.payload打印出eeeeeeeeeeeeeeeeeeee<úeeeeeeeeeeeeeeeeeeee²+!@<úHn½*Ìå«*¤ú¤F«*
。为什么超过20个字符?
这是我第一次使用C,所以请原谅我,如果这是显而易见的,但我甚至无法完成作业的核心,因为我遇到了语言问题。
答案 0 :(得分:2)
printf(),带有%s说明符,假设您正在向它发送一个以零结尾的字符串。因此它会在内存中读取字节,直到找到零(或'\0'
)。
strncpy不会向目标字符串追加零,除非在达到n个字符之前在源字符串中遇到零(此时目标字符串的其余部分用零填充,这当然会使其为零封端的)。
答案 1 :(得分:2)
strncpy
不会终止正在复制的字符串。
您必须手动终止字段
strncpy(packet.payload, message.data, sizeof(packet.payload) - 1);
packet.payload[sizeof(packet.payload) - 1] = '\0';
printf("%s\n", message.data);
printf("%s\n", packet.payload);
或将其视为固定大小的潜在无终止字符串:
strncpy(packet.payload, message.data, sizeof(packet.payload));
printf("%s\n", message.data);
printf("%.*s\n", sizeof packet.payload, packet.payload);
或者,您可以使用snprintf
(C99)来终止它,这更容易出错,因为它总是终止字符串。
snprintf(packet.payload, sizeof packet.payload, "%s", message.data);
printf("%s\n", message.data);
printf("%s\n", packet.payload);
答案 2 :(得分:0)
strncpy(packet.payload, message.data, sizeof(packet.payload));
packet.payload[sizeof(packet.payload) - 1] = 0;