構造体メンバをメンバー単位でコピーできますが、構造体の代わりにmemcpy
構造体をコピーできますか?ある構造体を別の構造体にコピーする
そうすることをお勧めしますか?
私の構造では、同じメンバーを持つ別の構造体にコピーしなければならないメンバとしての文字列もあります。それ、どうやったら出来るの?構造は、互換性のあるタイプである場合
構造体メンバをメンバー単位でコピーできますが、構造体の代わりにmemcpy
構造体をコピーできますか?ある構造体を別の構造体にコピーする
そうすることをお勧めしますか?
私の構造では、同じメンバーを持つ別の構造体にコピーしなければならないメンバとしての文字列もあります。それ、どうやったら出来るの?構造は、互換性のあるタイプである場合
普通の割り当てによるコピーは、短く読みやすく、抽象度が高いため、最適です。 (コードの人間の読者に)「これらのビットをここからそこにコピーする」と言うのではなく、読者にコピーのサイズの引数について考えるように要求するのではなく、単純な割り当て(「この値をここにここに」)。サイズが正しいかどうかについては心配する必要はありません。
構造が重く埋め込まれていると、割り当てがパディングをコピーする必要がなく(そしてどこにあるかを知っているので)、コンパイラがより効率的に放射するようになるかもしれませんが、mempcy()
はそうしませんコピーするバイト数を常に正確にコピーしてください。
文字列が実際の配列、つまり:
struct {
char string[32];
size_t len;
} a, b;
strcpy(a.string, "hello");
a.len = strlen(a.string);
は、その後、あなたはまだ、プレーンの割り当てを使用することができます。
b = a;
は完全なコピーを取得するには。このようにモデル化された可変長データの場合、配列全体が常にコピーされるので、これはコピーを行う最も効率的な方法ではありません。
そうすることによって、あなたはエイリアシングポインタ、および一般的にコピー動作後のポインタを所有している人、それは曖昧作っているので、しかし、ヒープ割り当てられたメモリへのポインタを含むそのコピーの構造体は、少し危険なことができます注意してください。
"ディープコピー"は実際には唯一の選択肢であり、その機能に入る必要があります。
は、はい、あなたは、のようなものとすることができます
memcpy (dest_struct, source_struct, sizeof (dest_struct));
あなたが知っておく必要がある唯一のものは、これが浅いコピーであるということです。つまり、特定の文字列を指しているchar *
がある場合は、の両方の構造が同じ文字列を指します。
これらの文字列フィールド(char *
自体ではなく、char *
が指し示すデータ)の内容を変更すると、他のものも変更されます。
あなたがstrdup
を使用し、手動で各フィールドを行うことなく、しかし非浅い文字列のコピーの追加ボーナスを簡単にコピーしたい場合:
memcpy (dest_struct, source_struct, sizeof (dest_struct));
dest_struct->strptr = strdup (source_struct->strptr);
これは、構造体の全体の内容をコピーし、その後、各構造体に別々の文字列を効果的に与えて、文字列を深くコピーします。
また、C実装にstrdup
(ISO標準の一部ではない)がない場合はget one from hereです。
C90は、あなたが簡単に使用することができますので:
dest_struct = source_struct;
として長い文字列は、アレイ内に記憶されるよう:
struct xxx {
char theString[100];
};
そうでなければ、それはポインタだ場合、あなた'LL手でそれをコピーする必要があります。
struct xxx {
char* theString;
};
dest_struct = source_struct;
dest_struct.theString = malloc(strlen(source_struct.theString) + 1);
strcpy(dest_struct.theString, source_struct.theString);
構造体を使用してファイルに書き込むことができます。 `char * 'としてキャストする必要はありません。 構造体のサイズも保持されます。単一文字列フィールド(から&に)移動するに
あなたはstrncpy
とAを使用する必要があります。 ( ハードメモリに振る舞うことは、多くの場合、1をRAMに似ているこの点は話題に最も近いではありませんが、それを推測。)一時的な文字列バッファ'\0'
が終了します。 どこかで、レコード文字列フィールドの長さを覚えておく必要があります。ポイント-2を回避するために、あなたはそれに合わせて構造体の中に、各文字列を埋め込むことができます例: NodeB->one=intvar;
floatvar2=(NodeA->insidebisnode_subvar).myfl;
struct mynode {
int one;
int two;
char txt3[3];
struct{char txt2[6];}txt2fi;
struct insidenode{
char txt[8];
long int myl;
void * mypointer;
size_t myst;
long long myll;
} insidenode_subvar;
struct insidebisnode{
float myfl;
} insidebisnode_subvar;
} mynode_subvar;
typedef struct mynode* Node;
...(main)
Node NodeA=malloc...
Node NodeB=malloc...
、 を使用すると、ドット表記を使用することができ、他のフィールドを移動するには
と NodeB->txt2fi=NodeA->txt2fi
...しかしscanf
ためのポイント-2で述べたように、あなたはまだ過渡文字列 プラスワンstrncpy
の必要があるでしょう、printf
:コボルのように振る舞いますそうでなければ、オペレータは長い入力(短い)、 は(スペースが埋め込まれた)切り捨てられませんでした。
(NodeB->insidenode_subvar).mypointer=(NodeA->insidenode_subvar).mypointer
は、ポインタエイリアスを作成します。NodeB.txt3=NodeA.txt3
は、コンパイラが拒否する原因: error: incompatible types when assigning to type ‘char[3]’ from type ‘char *’
ポイント-4は、同じtypedef
に属しているだけNodeB->txt2fi
& NodeA->txt2fi
ので動作します!
このトピックに正しいと簡単な答え私は、「(も文字の)配列がCに二級市民です」 In C, why can't I assign a string to a char array after it's declared? で発見!
なぜCでタグ付けされた質問の「メンバー関数」について話していますか? – unwind
構造体または少なくとも構造体の抽出を表示できますか?私は文字列がメンバー_function_ではないと仮定します"文字列"は文字配列か、動的に割り当てられるchar *か何か? – rjnilsson