- ベストアンサー
構造体の中でユーザー定義型の型を使いたい TurboC → VC++2005
昔、TurboCで作ったソースをVC++2005に置き換えようと難儀しています。 以下、構造体の中でユーザー定義型の型を使いたいのですが、 方法がわからず困っています。 ソースは途中で、コンパイルエラーになりませんが、肝心な所は コメントになっています。 詳しい方、教えていただけますか? /* 昔の古い構造体を VC++2005で使いたいです。 typedef struct _Test1{ char key[128]; char val[10]; } Test1; typedef struct _Test2{ char key[128]; Test1 val[10]; } Test2; */ #include <memory.h> using namespace System; using namespace System::Runtime::InteropServices; // テンプレート?でcharやshort型の配列はできるみたいです。 template<typename TYPE, size_t size> [StructLayout(LayoutKind::Sequential, Size=sizeof(TYPE) * size)] public value struct native_array{ TYPE elem; property TYPE default[int] { TYPE get(int index) { pin_ptr<TYPE> p = &this->elem; return p[index]; } void set(int index, TYPE value) { pin_ptr<TYPE> p = &this->elem; p[index] = value; } } }; public ref struct Test1{ String^ key; native_array<char, 10> val; Test1(){ key = "test1だよ"; pin_ptr<char> p = &this->val.elem; array<char>^ data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; pin_ptr<char> dat = &data[0]; memcpy(p, dat, sizeof(this->val)); } }; public ref struct Test2{ String^ key; // charやshortなどでなく、ユーザー定義型のTest1の型を // 配列として10個確保したい // 記述方法がわかりません。 Test2(){ key = "test2だけど、test1の型を使いたいです。"; // 記述方法がわかりません。 } }; int main(array<String^>^ args){ Test1 test1; Test2 test2; // Test1 Console::WriteLine(test1.key); for (unsigned i = 0; i < sizeof(test1.val) / sizeof(test1.val[ 0 ]); ++i) { Console::WriteLine(test1.val[ i ].ToString()); } // Test2 Console::WriteLine(test2.key); // 記述方法がわかりません。 return 0; }
- binma
- お礼率14% (11/78)
- C・C++・C#
- 回答数3
- ありがとう数0
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
マネージ型にするなら public ref struct Test1 { String^ key; array<char^> ^val; Test1(){ key1 = "Test1だよ"; val = gcnew array<char^>(10); for( int n=0; n < val.Length; n++ ) { val[n] = (char)(n + 1); } } } public ref struct Test2 { String^ key; array<ref struct Test1^> ^val; Test2() { key = "test2だけど、test1の型を使いたいです。"; val = gcnew array<ref struct Test1^>(10); for( int n = 0; n < val.Length; n++ ) { val[n] = gcnew Test1; } } } といった具合の宣言・コンストラクタではないかと思います main側では Test1 test1; Test2 test2; int n = 0, m= 0; Console::WriteLine( test1.key ); for ( n = 0; n < test1.val->Length; n++ ) { Console::WriteLine( test1.val[n] ); } Console::WriteLine( test2.key ); for ( n = 0; n < test2.val->Length; n++ ) { Console::WriteLine( test2.val[n]->key ); for ( m = 0; m < test2.val[n]->val->Length; m++ ) { Console::WriteLine( test2.val[n]->val[m] ); } } といった具合かと思います # マネージ開発はあまりしないので間違ってるかも知れませんが
その他の回答 (2)
- redfox63
- ベストアンサー率71% (1325/1856)
> ところで、マネージ開発はあまりしないということは、 ... 特に他意はないのですが私の仕事がマネージ環境をあまり意識したものを扱わないからということです VB.NETやC#でプログラムを書いたりもしますが C++でってことは殆んど無いんです いずれは やらなくちゃいけないんでしょうけど ...
- maku_x
- ベストアンサー率44% (164/371)
私は Visual C++ は分かりませんので、標準の C++(STLは使用)で書きますが、構造体はクラスで置き換えることができれば、従来の記法にこだわる必要は無いと思います。 (記述例) #include <iostream> #include <vector> using namespace std; const int ARRAY_SIZE_T1=10; const int ARRAY_SIZE_T2=3; class Test1 { string key; vector<char> val; public: // コンストラクタ Test1(char c_array[]) { key = "test1だよ"; copy( c_array, c_array + ARRAY_SIZE_T1, back_inserter(val) ); } // 出力 void print(void) { vector<char>::iterator it; cout << "'" << key << "', ("; for ( it=val.begin(); it!=val.end(); it++ ) { cout << *it << ","; } cout << ")" << endl; } }; class Test2 { string key; vector<Test1> val; public: // コンストラクタ Test2() { char t_array[ARRAY_SIZE_T2][ARRAY_SIZE_T1] = { { '0', '1', '2', '3', '4', '5', '6', '7', '7', '9' }, { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' }, { 'K', 'L', 'M', 'O', 'P', 'Q', 'R', 'S', 'T', 'U' } }; key = "test2だけど、test1の型を使いたいです。"; // ここは何を処理したいかによって記述方法が異なる。 // 以下はサンプル。 copy( &t_array[0], &t_array[ARRAY_SIZE_T2], back_inserter(val) ); } // 出力 void print(void) { vector<Test1>::iterator it; cout << "'" << key << "'" << endl; for ( it=val.begin(); it!=val.end(); it++ ) { (*it).print(); } } }; int main(void) { Test2 test2; // Test2 test2.print(); return 0; }
関連するQ&A
- 構造体を使ったプログラム
学校でC言語を勉強しています。(まだ初心者です) テストの成績を入力して、その結果を降順にソートしたいんですけど、 下記のプログラムでは、正常に動かないです。 struct seiseki { char nama; int sansuu; int rika; int goukei; }; ~~~~~~~~~~~~~~~~~~~~ struct seiseki class_a; struct seiseki class_b; struct seiseki *ptr1; struct seiseki *ptr2; ptr1 = class_a; ptr2 = class_b; ~~~~成績はあらかじめ入力済み~~~~ sout(class_a, 3); sout(class_b, 3); void sout(struct seiseki *p, int num) { struct seiseki temp; int count; int j; for (count = 1; num > count; count++) { temp = p[count]; for (j = count; j > 0 && p[j - 1].goukei < temp.goukei; j--) { p[j] = p[j - 1]; } p[j] = temp; p++; } } class_aだけを実行するプログラムだとちゃんと表示されますが、 一度でclass_aとclass_bを実行するプログラムだと表示がおかしくなります。 どなたか教えてください。
- ベストアンサー
- C・C++・C#
- 異なる構造体のデータのコピー
(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はデータの型が異なる場合、データのコピーはどのようにしたらよいでしょうか?
- ベストアンサー
- C・C++・C#
- 構造体のデータを丸ごとコピーしたい
C言語の構造体の勉強をしています。 構造体のデータを丸ごとコピーしたいのですが、今までは下記プログラムの★1の方法で1つ1つやっていました。 しかし変数が増えてきたのでできれば一度にコピーをしたいのですが、★2の方法では場合によってはゴミが含まれてしまいます。 そこで★3の方法で試すと今のところコピーできたのですが、これは安全なのでしょうか? ご存知の方がおられればお願いします。 また、もっといい方法があればご伝授いただけると助かります。 #include <stdio.h> #include <string.h> struct Sample{ int val1; int val2; }; void test(Sample *p, int num){ Sample d; switch(num){ case 1: //★1 d.val1 = p->val1; d.val2 = p->val2; break; case 2: //★2 memcpy(&d, p, sizeof(Sample)); break; case 3: //★3 d = *p; break; } printf("val1:%d, val2:%d\n", d.val1, d.val2); } int main(){ Sample s; s.val1 = 1; s.val2 = 2; test(&s, 1); return 0; }
- ベストアンサー
- C・C++・C#
- 構造体のメモリの確保のされかた
2つ質問があります。 1. #include <iostream> using namespace std; union Data { unsigned long val1_val2; struct { unsigned short val1; unsigned short val2; } value; }; int main(void) { Data data; data.val1_val2 = (40 /* val1 */ << (sizeof(data.value.val1) * 8)) + 10 /* val2 */; cout << "val1 = " << data.value.val1 << endl; cout << "val2 = " << data.value.val2 << endl; return 0; } 上記ソースコードを実行すると、「val1 = 10 val2 = 40」という結果がでます。val1は上位2バイトを指しているはずだと考えて書いたのですが、何が間違っているのでしょうか? 構造体は上に書いたメンバーを下位に割り当てていくのでしょうか? 2. 32ビットコンピューターでは構造体のサイズは4の倍数バイトになると聞いたのですが、VC++で struct s1{ char c; }; のサイズをsizeof演算子で見てみると、1バイトで struct s2{ unsigned bit: 1; }; のサイズは4バイトでした。 前者は本当に1バイトで扱われているのでしょうか? 以上2つよろしくお願いします。
- ベストアンサー
- C・C++・C#
- 構造体へのポインタ
すみません、構造体へのポインタの配列の扱いに困っています。 下記ソースの struct list *hashtable[HASHSIZE]; の箇所をmain部に入れた場合の 他の関数内での使用の仕方が全くわかりません。 どのように修正すれば良いのでしょうか。 申し訳ありませんが教えてください。 --------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> #define HASHSIZE 40 #define MAX_KW_LEN 256 #define NUM_KW 23 #define TRUE 1 #define FALSE 0 struct list { char keyword[MAX_KW_LEN]; struct list *next; /* 次の list へのポインタ */ }; struct list *hashtable[HASHSIZE]; /* ハッシュテーブル */ /* キーワード ( Cの予約語 ) */ static char kw[NUM_KW][MAX_KW_LEN] = { "auto", "break", "double", "enum", "char", "continue", "extern", "float", "for", "int", "long", "register", "short", "signed", "static", "struct", "typedef", "union", "unsigned", "return", "void", "volatile", "while" }; int Hash(char *key); void InitHTable(void); int FindKeyWord(char *key); void ListKeyWord(void); void FreeKeyWord(void); int main(void); int Hash(char *key) { int hashval = 0; while (*key != '\0') hashval += *key++; return (hashval % HASHSIZE); } void InitHTable(void) { int i; struct list *p, *q; int hashval; for (i = 0; i < NUM_KW; i++) { printf("%d\n",i); if ((FindKeyWord(kw[i])) == FALSE) { /* 登録されていなかったら */ /* メモリを割り付ける */ if ((p = (struct list *)malloc(sizeof(struct list))) == NULL) { fprintf(stderr, "メモリ不足です。\n"); exit(2); } strcpy((*p).keyword, kw[i]); hashval = Hash(kw[i]); /* ハッシュ値を求めて */ if (hashtable[hashval] == NULL) { /* 未登録なら */ hashtable[hashval] = p; /* p の指すアドレスを登録 */ p->next = NULL; /* リストの末尾に NULL を追加 */ } else { /* 既に登録していたら */ q = hashtable[hashval]; while (q->next != NULL) { /* データがなくなるまで */ q = q->next; /* リストをたどる */ } q->next = p; /* リストの末尾に p の指すアドレスを登録 */ p->next = NULL; /* その末尾に NULL を追加 */ } } } } int FindKeyWord(char *key) { struct list *p; for (p = hashtable[Hash(key)]; p != NULL; p = p->next) if (!strcmp(key, (*p).keyword)) /* 登録済みなら */ return (TRUE); /* TRUE を返す */ return (FALSE); /* 未登録ならFALSE を返す */ } void ListKeyWord(void) { int i; struct list *p; for (i = 0; i < HASHSIZE; i++) for (p = hashtable[i]; p != NULL; p = p->next) /* p が NULL でなければ */ /* ハッシュ値とキーワードを表示 */ printf("予約語:%s ハッシュ値:%d:\n", (*p).keyword, Hash((*p).keyword)); } /* malloc( ) で割り付けたメモリを解放 */ void FreeKeyWord(void) { int i; struct list *p, *q; for (i = 0; i < HASHSIZE; i++) for (p = hashtable[i]; p != NULL; ) { /* p が NULL でなければ */ q = p->next; /* p->next を保存 */ free(p); /* メモリを解放 */ p = q; /* p->next を p に代入 */ } } int main(void) { char word[MAX_KW_LEN]; int i; InitHTable( ); ListKeyWord( ); for (i = 0; i < 4; i++) { printf("Cの予約語を入力して下さい "); fgets(word, 128, stdin); if ((FindKeyWord(word)) == TRUE) printf("%s は登録済みです。\n", word); else printf("%s は未登録です。\n", word); } FreeKeyWord( ); }
- 締切済み
- C・C++・C#
- 構造体を型の異なる構造体に代入
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です。
- ベストアンサー
- C・C++・C#
- c#でサンプルゲームを作ってみた
c#でサンプルゲームを作ってみたのですがエラーがでるので間違っている所を指摘してくださいm(__)m using System; class test1 { public int HP; public int ATK; public int DF; } public class test2 { public static void Main() { test1 player1 = new test1(); test1 player2 = new test1(); player1.HP = 150; player2.HP = 150; char ch; char ken; char zyuu; char chois; int buki; for(;;){ do{ Console.WriteLine(" 使う武器を選んでください"); Console.WriteLine("¥n"); Console.WriteLine(" 1. 刀 "); Console.WriteLine("¥n"); Console.WriteLine(" 2. 拳銃 "); Console.WriteLine("¥n"); Console.WriteLine(" 3. 素手 "); Console.WriteLine(" 終了させたい場合は e"); do{ ch = (char) Console.Read(); } while(ch == '¥n' | ch == '¥r'); }while(ch < '1' | ch > '3' & ch != 'n'); if(ch == 'n') break; Console.WriteLine("¥n"); switch(ch){ case '1': Console.WriteLine(" どの刀を使いますか?"); Console.WriteLine(" 1. 太刀"); Console.WriteLine(" 2薙刀"); ken = (char) Console.Read(); while(ken == '¥n' | ken == '¥r'); Console.WriteLine("¥n"); switch(ken){ case '1': buki = 15; break; case '2': buki = 14; break; } case '2': Console.WriteLine(" どの銃を使いますか?"); Console.WriteLine(" 1.マシンガン"); Console.WriteLine(" 2.リボルバー"); zyuu = (char) Console.Read(); while(zyuu == '¥n' | zyuu == '¥r'); Console.WriteLine("¥n"); switch(zyuu){ case'1': buki = 10; break; case'2': buki = 15; break; } case'3': buki = 8; break; } Console.WriteLine("敵が現れた!"); for(;;){ if(plyer1.HP < 0) break; else(player2.HP < 0 ) break; Console.WriteLine(" 1.攻撃¥n 2.防御"); chois = (char) Console.Read(); while(chois == '¥n' | chois == '¥r'); Console.WriteLine("¥n"); switch(chois){ case'1': Console.WriteLine("player1の攻撃!!"); player2.HP = player2.HP - (buki + 10) - 5; Console.WriteLine("%d, player2.HP") ; Console.WriteLine("player2の攻撃!!"); player1.HP = player1.HP - (20 - 5); break; case'2': Console.WriteLine(" player1はガードした!!"); Console.WriteLine("player2の攻撃!!"); Console.WriteLine(" しかしplayer1は攻撃を防いだ!"); break; } } } } }
- 締切済み
- その他(ゲーム)
- リストの削除について(構造体)
リストの削除のプログラムを実行して行ってみると、リストの削除処理中にプログラムが終わって変更後処理がうまく表示されません。どこが間違っているかが分からないしだいです。返答のほどよろしくお願いいたします。 #include<stdio.h> #include<malloc.h> #include<string.h> struct list{ char name[20]; int age; struct list *next; }; void main(void) { struct list *head, *p, *n, *old; char key[20]; /*ダミーノード作成*/ head = (struct list*)malloc(sizeof(struct list)); old = head; while(p = (struct list*)malloc(sizeof(struct list)), printf("name age入力\n"), scanf("%s %d", p -> name, &p -> age) != EOF){ old -> next = p; old = p; } free(p); old -> next = NULL; p = head -> next; printf("変更前リスト\n"); while(p != NULL){ printf("name:%s age:%d\n",p -> name, p -> age); p = p -> next; } printf("削除key入力(name)\n"); gets(key); n = head; while(n != NULL){ old = n; n = n -> next; //printf("n -> name %s\n", n -> name); if(strcmp(n -> name, key) == 0){ printf("%s削除\n", key); //printf("n -> name %s old -> name %s\n", n -> name, old -> name); old -> next = n -> next; } } p = head -> next; printf("変更後リスト\n"); while(p != NULL){ printf("name:%s age:%d\n", p -> name, p -> age); p = p -> next; } }
- ベストアンサー
- C・C++・C#
- 構造体のメンバーの静的なサイズ取得
構造体のメンバーをヘッダーファイル中で得たい場合、 以下のような方法以外になにか方法はないでしょうか? 単純に XXXX x;と宣言してそれを sizeof(x.chwk)と 使うというような方法以外で なにかあれば教えてください。 ---------------------------------------- typedef struct { char chwk[100]; } XXXX; typedef struct { char chwk[ sizeof(( (XXXX*)0)->chwk ) ]; } YYYY; main(int arc, char *arg[] ){ YYYY y; printf( " YYYY chwk size = %d\n", sizeof(y.chwk)); }
- ベストアンサー
- C・C++・C#
補足
ありがとうございます。 若干修正し、コンパイルすると動作しました。 マネージ型について望んでいた通りのものでした。 ところで、マネージ開発はあまりしないということは、 マネージ開発のメリットが少ないため、まだまだアンマネージ開発?が主流と読み取りますが、マネージ型のデメリットは何なのでしょうか? 速度が遅いだけなのでしょうか? アンマネージ型のソースも見たいですが、これは普通のTurboCで動作させる typedef struct _Test1{ char key[128]; char val[10]; } Test1; typedef struct _Test2{ char key[128]; Test1 val[10]; } Test2; で動作させるものでしょうか? //VC++2005 マネージ型 using namespace System; public ref struct Test1 { String^ key; array<char^> ^val; Test1(){ key = "Test1だよ"; val = gcnew array<char^>(10); for( int n=0; n < val->Length; n++ ) { val[n] = (char)(n + 1); } } }; public ref struct Test2 { String^ key; array<ref struct Test1^> ^val; Test2() { key = "test2だけど、test1の型を使いたいです。"; val = gcnew array<ref struct Test1^>(10); for( int n = 0; n < val->Length; n++ ) { val[n] = gcnew Test1; } } }; int main( array<String^>^args){ Test1 test1; Test2 test2; int n = 0, m= 0; Console::WriteLine( test1.key ); for ( n = 0; n < test1.val->Length; n++ ) { Console::WriteLine( test1.val[n] ); } Console::WriteLine( test2.key ); for ( n = 0; n < test2.val->Length; n++ ) { Console::WriteLine( test2.val[n]->key ); for ( m = 0; m < test2.val[n]->val->Length; m++ ) { Console::WriteLine( test2.val[n]->val[m] ); } } }