【问题标题】:strncopy copying more than n charactersstrncpy 复制多于 n 个字符
【发布时间】:2010-11-18 01:57:29
【问题描述】:

我得到了一个程序的外壳,必须填写一些函数。

我有两个自动创建并传递给我必须定义的函数的结构。

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,如果这很明显,请原谅我,但我什至无法进入作业的核心,因为我在语言方面遇到了问题。

【问题讨论】:

  • 如果您希望 %.20s 处理可能不是以 null 结尾的 20 字节字段,请在您的 printf 格式字符串中使用它。

标签: c strncpy


【解决方案1】:

printf() 带有 %s 说明符,假定您发送的是以零结尾的字符串。所以它会读取内存中的字节,直到找到零(或'\0')。

strncpy 不会将零附加到目标字符串,除非在到达 n 个字符之前在源字符串中遇到零(此时目标字符串的其余部分用零填充,这当然会导致它为零-终止)。

【讨论】:

  • 更准确地说,strncpy 不会在源字符串为 n 个字符或更长的情况下将零附加到目标字符串。
【解决方案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);

【讨论】:

    【解决方案3】:
    strncpy(packet.payload, message.data, sizeof(packet.payload));
    packet.payload[sizeof(packet.payload) - 1] = 0;
    

    【讨论】:

      猜你喜欢
      • 2012-05-12
      • 2010-11-13
      • 1970-01-01
      • 2022-01-12
      • 2016-08-07
      • 1970-01-01
      • 2020-09-27
      • 1970-01-01
      相关资源
      最近更新 更多