異なる構造体のデータのコピー

このQ&Aのポイント
  • 異なる構造体のデータをコピーする方法について解説します
  • 構造体のメンバのデータを別の構造体にコピーする際の方法についてご紹介します
  • 異なる構造体のメンバデータのコピー方法や異なるデータ型のメンバの扱いについて解説します
回答を見る
  • ベストアンサー

異なる構造体のデータのコピー

(1)で受け取った構造体のメンバのデータを (2)の構造体のメンバにコピーしたいと考えています。 (1) typedef struct _recvData{ int data01; int data02; char data03; char data 04; char data05; char data 06; char data07; char data08; char data09; char data10; char array01[16]; char array02[16]; } recvData; (2) typedef struct _sendData{ int header; int data01; int data02; char data03; char data 04; char data05; char data 06; char data07; char data08; char data09; char data10; int array01[4]; int array02[4]; } sendData; そこで2点ほどおしえていただきたく、お願い致します。 (1)構造体が微妙に異なるため、各メンバ変数に値をそれぞれ代入していくしか方法がないのでしょうか? (2)array01, array02はデータの型が異なる場合、データのコピーはどのようにしたらよいでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
回答No.5

>(1)構造体が微妙に異なるため、各メンバ変数に値をそれぞれ代入していくしか方法がないのでしょうか? struct _recvData rData; struct _sendData sData; として memcpy(&sData.data01, &rData, sizeof(rData)); という連続したメモリー領域としてコピーが可能です。 C言語では、 構造体のアドレスはその先頭のメンバーのアドレスと一致する ということが保障されています。 この手法には副作用があります。 ■ 利点 プログラムメモリの消費量が小さくなる。 ■ 欠点 送受信データの構造体の定義が反映されないため、 構造体のメンバーが変更されるとバグが発生する確率が高くなる。 構造体に個別の変数を代入方法は マクロと関数にする方法がありますが どちらが良いかは固有の問題ではなく、一般論です。 >(2)array01, array02はデータの型が異なる場合、データのコピーはどのようにしたらよいでしょうか? エンディアン (endianness)が異なる場合 バイト列を並べ替える必要があります。 例 for (u_char *s = (u_char *)&sData.array01[0], int i = sizeof(sData.array01[0])/sizeof(rData.array01[0]) - 1; i >= 0 ; i--) *s++ = (u_char)rData.array01[i]; エンディアンが等しい場合は、 他の回答にもあるように、そのままバイト列としてコピーすれば良いでしょう。 エンディアンの変換が必要である場合、 通信プロトコルのレイヤーが何処にあるかで 変換するかしないかを決定します。 アプリケーションのレイヤーでの互換性を維持する場合は、アプリケーションで それより下位の通信プロトコルの場合には その階層に一致するドライバーで変換するべきです。

その他の回答 (4)

  • opera-man
  • ベストアンサー率26% (111/414)
回答No.4

同変数名のデータをコピー。 headerは対応する変数ないので未処理。 int型は4バイト。 を前提条件として、 data1~data10までは、 memcpy()で&_recvDataを&_sendData.data01へ16バイト分コピーでOKです。 array01,array02については、どういう変換をするかという 仕様次第ではありますが、例えば char array01[4]=0x12, 0x34, 0x56, 0x78 というデータを int array01[0]=0x12345678 というように代入したいとすれば、 int array01[0]=(0x78>>24)+(0x56>>16)+(0x34>>8)+0x12 でいけると思います^^ ※もし、処理系がビックエンディアンなら、 memcpy()するサイズを48バイト分コピーでいけると思います!

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.3

つ「共用体」 headerが足りない分以外は基本的に同じサイズっぽい(パディング注意)ので、recvDataの先頭にintのダミーメンバー突っ込んでしまえば一応なんとかなりそう。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

「構造体が微妙に異なる」というか, そもそもタグが違うから別物. よって「メンバごとちまちま代入する」しかない. 特殊な条件がそろえば memcpy とかが使える場面もないわけではないが, それを考えるくらいなら「微妙に異なる」ところ以外をまとめて構造体にしてしまえ.

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

>(1)構造体が微妙に異なるため、各メンバ変数に値をそれぞれ代入していくしか方法がないのでしょうか? おそらく、そうせざるを得ないと思います。 >(2)array01, array02はデータの型が異なる場合、データのコピーはどのようにしたらよいでしょうか? 入力データがどうなっているときに、出力データをどうしたいかによると思います。 エンディアンが関係するかもしれません。 ところで、data03~data10は、配列にするわけにはいかないのでしょうか。

関連するQ&A

  • リトルエンディアン→ビッグエンディアン

    (1)リトルエンディアン typedef struct recvData{  int a;  unsigned char b[16]; unsigned char c[8]; unsigned int d[4]; } recvData_t; recvData_t rData; (2)ビッグエンディアン typedef struct sendData{  int a;  unsigned int b[4]; unsigned int c[2]; unsigned int d[4]; } sendData_t; sendData_t sData; 上記のようなリトルエンディアンの構造体の各メンバのデータを、ビッグエンディアンの構造体の各メンバのデータにそれぞれ格納するには どうしたらよいでしょうか?

  • 構造体を型の異なる構造体に代入

    C言語初心者です。 今回の質問は入力された構造体のメンバのデータを型の異なる構造体に代入したいのですが、毎回コンパイラにおこられてしまいます(汗)具体的には typedef struct MSG{ longint type; int flg; int Dt[64]; }t_msg; このDt[64]を以下の構造体に代入します。 typedef struct SC_MSG{ char a; char b; short c; char d; char e; short f; }t_sc_msg; その際、異なる関数で処理するため、 main(){ foo(&t_msg); }; void foo(t_msg *pt_msgdt){ t_sc_msg = (*pt_msgdt+8); ココがエラーになってしまいます。 何か、根本的な間違いをおかしている気がします。 ご指導の方、宜しくお願いします。 ちなみにOSはLinuxでコンパイラーはgccです。

  • 構造体型のポインタ変数を含む構造体

    struct seiseki_tag { Int32 math ; Int32 english ; Int32 science; } ; typedef struct seiseki_tag SEISEKI ; struct personal_tag { Char name ; Int32 num ; SEISEKI *sptr } : typedef struct personal_tag PERSONAL ; struct info_tag { PERSONAL person_info ; } ; typedef struct info_tag INFO ; たとえば、上記のように3つの構造体があり、PERSONAL構造体のメンバーに SEISEKI構造体の型を持つポインタ変数が含まれているような場合で、下記のように INFO型のポインタ変数からSEISEKI構造体のメンバーを参照する方法を教えてください。 PERSONAL構造体メンバーのnameやnumは INFO *info ; info->person_info.name ; info->person_info.num ; のように参照すると思いますが、sptrが示すSEISEKI構造体のメンバーへの アクセスができません。下記のように参照を試みたのですがコンパイルは 通るのですが、実際に参照できていませんでした。 INFO *info ; SEISEKI *seiseki ; seiseki = info->person_info.sptr ; seiseki->math ; 判りにくい説明で申し訳ありませんが、どなたか教えていただければと思います。 よろしくお願いいたします。

  • 【VC++2005 MFC】構造体のコピーについて

    【VC++2005 MFC】構造体のコピーについて 構造体をコピーする時、単純に「=」で代入しているのですが、先輩に 「それじゃコピー出来ないから各メンバごとに代入するような関数作れ」 と言われました。 私自身、C言語の初心者ですが、ネットで調べてみると、単純に「=」で代入出来る ような気がしております。 ただ拝見したサイトに記載されている構造体は型が「int」「char」なのですが、 「CString」を使っていたり、構造体の中に更に構造体が入っていたりする場合も 単純に「=」で代入出来るのでしょうか? (というか、実際にコーディング、デバッグして、コピー出来ている事は確認しているん ですが、先輩いわく、「CStringとかのクラスが含まれている場合はダメだと思う。 メモリが壊れると思う」との事でした。)

  • 構造体から他の構造体への代入

    現在C言語で簡単なプログラミングを書いているのですが、 構造体(1)(下記参照)から、構造体(2)(下記参照)への代入の方法がわからず悩んでいます。もしよければ手を貸してください!! 標準関数などがないということはわかったので、 地道に代入を行いたいです。 イメージ・・・(data[n].b = moji[n].d;) (1)struct list_kouzou{ int a; char b[30]; char c[8]; }data[100]; (2)struct list_tai{ char d[30]; }moji[15];

  • 構造体

    構造体を受け取って、メンバの値を変数に代入する部分での質問です。 lParamには構造体のアドレスが入っています。 strcpy(buf, ((struct mpoint*)lParam)->r); これによって構造体のrメンバの文字列値をbufにコピーしたいのですが、文法が違うようなので正しく直したものを教えてください。

  • C++言語で、構造体のコピーは可能(しても良い)のでしょうか?

    C++言語で、構造体のコピーは可能(しても良い)のでしょうか? 問題がある場合は、なぜだめなのか知りたいです。 構造体は可変長ではありません。 typedef struct kumi { char namae[10]; int ten; }Kumi; Kumi a, b; strcpy(a.namae, "AAA"); a.ten = 50; b = a;

  • 構造体のポインタにNULLが入らない

    typedef struct tag{ int number; char name[10]; struct tag *next; }DATA; という構造体があって、 DATA *p; と宣言し、 p->next == NULL; とすることはできないんですか? セグメンテーション違反になってしまうのですが。 pが指すnextにNULLを入れるにはどうしたらいいのでしょうか?

  • 構造体の静的な初期化

    構造体の静的な初期化で、初期化が書かれていないメンバーは、 どうなるのでしょうか。。? たとえば・・・ // 構造体の宣言 strcut MY_STRUCT {    int data1 ;    int data2 ;    int data3 ;    int data4 ; } ; // 変数宣言&初期化 static strcut MY_STRUCT st = {    .data1 = 100,    .data3 = 300 } ; ネットで調べると、 初期化で指示されていないメンバーは0に初期化される、 という記述も一つだけ見つけたのですが・・・これはC言語(C99)の仕様でしょうか? それともコンパイラ依存の仕様でしょうか?

  • 構造体のメンバ参照について(C言語)

    初めて書き込みする,taroimotenです. 以下のプログラムを作ってみたのですが, メモリ参照エラーが表示され,うまく動きません. アドバイスおねがいします! #include <stdio.h> #include <stdlib.h> // 型宣言. typedef struct data DATA; typedef struct coords COORDS; // 構造体の定義. struct data{ COORDS *pnt[3]; }; struct coords{ float r1; float r2; }; int main(void) { DATA *ptr; DATA x; // ポインタ変数の初期化. ptr = &x; // メンバへの値の代入. ptr->pnt[0]->r1 = 100.0; printf(" r1 : %f \n",ptr->pnt[0]->r1); return EXIT_SUCCESS; }