strncopy复制超过n个字符

时间:2010-11-18 01:57:30

标签: c strncpy

我给了一个程序的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,所以请原谅我,如果这是显而易见的,但我甚至无法完成作业的核心,因为我遇到了语言问题。

3 个答案:

答案 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;