开发者

strncopy copying more than n characters

I'm given a shell of a program and have to fill in a few functions.

I have two structs I am given that are automatically created and passed to the functions I must define.

typedef struct {
    char data[20];
} msg;

typedef struct {
     int seqnum;
     int acknum;
     int checksum;
     char payload[20];
 } pkt;

Say I have to define this function foo and have created it as such:

void foo(msg message) {
    printf("%s\n", message.data);
}

When that function is called, it prints out ddddddddddddddddddddôÑ@<úHn½*Ìå«*¤ú¤F«*. Unless I am incorrect, shouldn't it only be able to hold 20 characters? I am not actually creating msg.

It gets even stranger if I copy msg.data to 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 prints out the same as before, but packe开发者_开发知识库t.payload prints out eeeeeeeeeeeeeeeeeeee<úeeeeeeeeeeeeeeeeeeee²+!@<úHn½*Ìå«*¤ú¤F«*. Why is it more than 20 characters?

This is my first time using C so forgive me if this is obvious but I can't even get to the core of the assignment since I'm having trouble with the language.


printf(), with a %s specifier, assumes you are sending it a zero-terminated string. So it reads bytes in memory until it finds a zero (or '\0').

strncpy does not append a zero to your destination string unless a zero is encountered in the source string before n characters are reached (at which point the rest of the destination string is padded with zeros, which of course causes it to be zero-terminated).


strncpy does not terminate the string being copied.

You either have to manually terminate the field,

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);

or treat it as a fixed-size potentially unterminated string:

strncpy(packet.payload, message.data, sizeof(packet.payload));
printf("%s\n", message.data);
printf("%.*s\n", sizeof packet.payload, packet.payload);

Alternatively, you may keep it terminated with snprintf (C99), which is less error-prone, as it always terminates the string.

snprintf(packet.payload, sizeof packet.payload, "%s", message.data);
printf("%s\n", message.data);
printf("%s\n", packet.payload);


strncpy(packet.payload, message.data, sizeof(packet.payload));
packet.payload[sizeof(packet.payload) - 1] = 0;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜