0

memcpy で次のエラーが発生します。コンパイルエラーは発生しませんが、私が想像する結果は得られません。これまで memcpy を使用したことがないので、単純な間違いを犯していると確信しています。以前の質問を見回しましたが、構造のあるものを見つけることができませんでした。独立変数では memcpy を使用できますが、構造体では使用できません。

誰かが私の間違いを指摘できれば、それは素晴らしいことです。

#include <stdio.h>
#include <string.h>


int main() {
 struct st{
 char c1[12];
 char c2[32];
 char c3[3];
 char c4[7];
 char c5[13];
 char c6[5];
 char c7[10];
 };
 struct st s;
 char s1[] = "part number";
 char s2[] = "j9uijd9d09fj";
 char s3[] = "abc";
 char s4[] = "seven";
 char s5[] = "aaaaaaaa";
 char s6[] = "ptype";
 char s7[] = "user";
 memcpy(s.c1,s1,sizeof(s.c1));
 memcpy(s.c2,s2,sizeof(s.c2));
 memcpy(s.c3,s3,sizeof(s.c3));
 memcpy(s.c4,s4,sizeof(s.c4));
 memcpy(s.c5,s5,sizeof(s.c5));
 memcpy(s.c6,s6,sizeof(s.c6));
 memcpy(s.c7,s7,sizeof(s.c7));
 printf("%s\n",s.c1);
 printf("%s\n",s.c2);
 printf("%s\n",s.c3);
 printf("%s\n",s.c4);
 printf("%s\n",s.c5);
 printf("%s\n",s.c6);
 printf("%s\n",s.c7);
 return 0;
}

私が得ている出力:

part number
j9uijd9d09fj
abcseven
seven
aaaaaaaa
ptypeuser
user

ありがとう!!!

4

5 に答える 5

4

c3構造体のサイズをto4c6toに変更6して、ターミネータを許可しNULLます。

struct st{
    char c1[12];
    char c2[32];
    char c3[4]; /* putting 'abc' which is 4 chars */
    char c4[7];
    char c5[13];
    char c6[6]; /* putting 'ptype' which is 6 chars */
    char c7[10];
};
于 2012-09-17T12:46:00.977 に答える
1

あなたのコードは2つの点で間違っています:

  1. s.c3は3文字の長さであるため、余分なNULバイトを入れる余地はありません。そのため、印刷時に次のものと連結して取得します。
  2. 場合によっては、元の文字列よりも多くのバイトをコピーしていますmemcpy(s.c2,s2,sizeof(s.c2))。32バイトをコピーしていますが、元の文字列ははるかに短いです。それは未定義の振る舞いです。

使用したい確率strcpy()

またはstrncpy、しかし、注意してください!この関数は、ほとんどの人が考えていることを実行しません...使用する前に、ドキュメントを少なくとも2回読んでください。

于 2012-09-17T12:51:06.547 に答える
1

printfwith%sは、null で終わる文字列を出力します。s3(およびs6) この場合、ヌル終了文字は によって上書きされるcためprintf、次の文字に到達すると印刷が停止しsevenます。

于 2012-09-17T12:46:52.177 に答える
0

この構造体では、メンバーc3は 3 文字の配列です。次に、 4 つの文字をコピーします。文字列には文字列を終了する余分な文字があるため、文字列"abc"は実際には'a''b''c'およびターミネータの4 文字であることに注意して'\0'ください。

c6構造体のメンバーについても同様です。

于 2012-09-17T12:48:09.733 に答える
0

あなたが直面している問題は、文字シーケンスの NUL ターミネータが欠落していることです。

それらを作成するときの文字シーケンスは、入力した文字数よりも常に 1 文字長くなります。最後の追加文字は NUL ターミネータです。

したがって、コピーする配列は、コピーする文字数よりも 1 文字長くする必要があります。c3文字数が少なすぎるため、NUL ターミネータが失われます。

printf次に、NUL ターミネータが表示されるまで、文字列を 1 文字ずつ出力します。欠落している場合はprintf、最初のバイトに到達するまでメモリの読み取りを続け0x00ます。この場合、構造体を使用しているので幸運です。構造体はメモリの 1 つのブロックに書き込まれるためprintf、次のフィールドにドロップするだけです。

構造内の配列のサイズが、コピーする文字シーケンスよりも常に大きいことを確認するだけで、問題を解決できます。

于 2012-09-17T12:53:32.927 に答える