1

プログラムのシェルが与えられ、いくつかの関数を入力する必要があります。

自動的に作成され、定義する必要のある関数に渡される2つの構造体があります。

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を使うのは初めてなので、これが明らかな場合は許してください。しかし、言語に問題があるため、課題の核心に到達することすらできません。

4

3 に答える 3

2

%s 指定子を指定した printf() は、ゼロで終わる文字列を送信していると想定します。したがって、ゼロ (または ) が見つかるまでメモリ内のバイトを読み取ります'\0'

strncpy は、n 文字に達する前にソース文字列でゼロが検出されない限り、宛先文字列にゼロを追加しません (この時点で、宛先文字列の残りの部分はゼロで埋められます。これにより、もちろんゼロで終了します)。 .

于 2010-11-18T02:00:22.467 に答える
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);

または、(C99) で終了したままにしておくこともできますsnprintf。これは、常に文字列を終了するため、エラーが発生しにくくなります。

snprintf(packet.payload, sizeof packet.payload, "%s", message.data);
printf("%s\n", message.data);
printf("%s\n", packet.payload);
于 2010-11-18T02:02:55.463 に答える
0
strncpy(packet.payload, message.data, sizeof(packet.payload));
packet.payload[sizeof(packet.payload) - 1] = 0;
于 2010-11-18T02:03:13.650 に答える