• 締切済み

構造体を宣言と共に初期化する方法

構造体を宣言と共に初期化する方法はないのでしょうか? もしないのでしたら初期化用の関数を作ってそれを呼び出すしかないのでしょうか? ↓このような感じで ---kudamono.cppの内容 --- #include <stdio.h> struct{ static const char *name[5]; static const char *num[5]; }kudamono; void kuda(void){ kudamono.name[0] = "りんご"; kudamono.name[1] = "みかん"; kudamono.name[2] = "オレンジ"; kudamono.name[3] = "もも"; kudamono.name[4] = "キウイ"; kudamon.num[0] = "1個"; kudamon.num[1] = "3個"; kudamon.num[2] = "5個"; kudamon.num[3] = "2個"; kudamon.num[4] = "4個"; } --- main.cppの内容 --- #include <stdio.h> void kuda( void ); void main( void ){ printf( "%sが%sある" , kudamono.name[0] , kudamon.num[0] ); }

みんなの回答

  • wormhole
  • ベストアンサー率28% (1622/5659)
回答No.6

>おかしいですね私の環境ではコンパイルエラーになっていないみたいですが おかしいのは、あなたが質問文・お礼・補足に書かれているソースです。 抜粋のつもりなのかもしれませんが質問内容と無関係のとこまでおかしいので抜粋になってません。

nanaka2223
質問者

お礼

もしかして構造体をポインタにいれてファイルを2つに分けて表記する場合、宣言と共に初期化しても意味がなかったりしますか?

nanaka2223
質問者

補足

ソースを間違えていて申し訳ありません。

全文を見る
すると、全ての回答が全文表示されます。
  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.5

>おかしいですね私の環境ではコンパイルエラーになっていないみたいですが >私の開発環境は現在 windows xp Visual C++ 2008なのですが環境によって左右するとか起こりますか? WinXP(SP3)とVC++2008EE(SP1)で質問にあるソースを。 # kudamonをkudamonoに修正してます。 [ファイル][新規作成][プロジェクト]で「Win32 コンソールアプリケーション」を選択。 「空のプロジェクト」として、ソリューションエクスプローラの「ソース ファイル」で右クリック、 [追加][新しい項目]でソースを2つ追加して保存します。 で、ビルドを実行。 1>------ すべてのリビルド開始: プロジェクト: qa8015313, 構成: Debug Win32 ------ 1>プロジェクト 'qa8015313'、構成 'Debug|Win32' の中間出力ファイルを削除しています。 1>コンパイルしています... 1>kudamono.cpp 1>main.cpp 1>d:\documents and settings\XXXX\my documents\visual studio 2008\projects\qa8015313\qa8015313\main.cpp(7) : error C2065: 'kudamono' : 定義されていない識別子です。 1>d:\documents and settings\XXXX\my documents\visual studio 2008\projects\qa8015313\qa8015313\main.cpp(7) : error C2228: '.name' の左側はクラス、構造体、共用体でなければなりません 1> 型は ''unknown-type'' です。 1>d:\documents and settings\XXXX\my documents\visual studio 2008\projects\qa8015313\qa8015313\main.cpp(7) : error C2065: 'kudamono' : 定義されていない識別子です。 1>d:\documents and settings\XXXX\my documents\visual studio 2008\projects\qa8015313\qa8015313\main.cpp(7) : error C2228: '.num' の左側はクラス、構造体、共用体でなければなりません 1> 型は ''unknown-type'' です。 1>コードを生成中... 1>ビルドログは "file://d:\Documents and Settings\XXXX\My Documents\Visual Studio 2008\Projects\qa8015313\qa8015313\Debug\BuildLog.htm" に保存されました。 1>qa8015313 - エラー 4、警告 0 ========== すべてリビルド: 0 正常終了、1 失敗、0 スキップ ========== となりました。

nanaka2223
質問者

補足

ファイルをひとつの場合はエラーはでません。 #include <stdio.h> static struct{ const char *name; int num; } kudamono[5] = { {"りんご", 1}, {"みかん", 3}, {"オレンジ", 5}, {"もも", 2}, {"キウイ", 4} }; void main( void ){ printf( "%sが%dある\n" , kudamono[0].name , kudamono[0].num ); } しかし、ファイルを2つに分ける時がうまくいっていません。 前回の最後のソースを書き忘れがあったみたいですね --- main.cpp の内容 --- #include <stdio.h> #include "betu.h" void main( void ){ betu(&a); //書き忘れ部分 printf( "%d" , a ); } --- betu.h の内容 --- static int a; void betu( int *a ); --- betu.cpp の内容--- #include <stdio.h> #include "betu.h" void betu( int *a ){ *a = 5; } ソースを間違えていて申し訳ありません。

全文を見る
すると、全ての回答が全文表示されます。
  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.4

>このような感じになりましたが問題ありますか? 「初期化」としては問題ないかと。 ちなみにkuda()内でやっているのは初期化ではなく代入です。 「C言語 初期化 代入」あたりで検索してみるとよいかと。 # まあ、kuda()内の用に最初の代入を初期化と言ったりするコトもあったりはしますけどね。 >この部分は構造体をポインタにする方法がわからなかったものでかけませんでした 前回( http://okwave.jp/qa/q7992723.html )のとこでの理解がいまいちな状態で閉じられてしまいましたからねぇ……。 ポンイタとか関係ないかと。 それとは別に、「main.cppにとってkudamonoやkudamonが不明な状態」は代わりありません。 宣言もなにもされていないのですからコンパイルエラーになっているはずですが…。 で、kudamonoやkudamonは「kudamono.cppにあるグローバル変数」なのですから、kuda()で値を代入するのに呼び出し元からアドレスを渡す必要はありません。 main.cppにとってはそんなの関係ないコトです。

nanaka2223
質問者

お礼

あれ、もしかしてこう書けばいいってことですか? ---kudamono.cppの内容 --- #include <stdio.h> void kuda(void){ static struct{  const char *name;  int num; } kudamono [5] = {  {"りんご", 1},  {"みかん", 3},  {"オレンジ", 5},  {"もも", 2},  {"キウイ", 4} }; } --- main.cppの内容 --- #include <stdio.h> void main( void ){ kuda(); printf( "%sが%sある" , kudamono.name[0] , kudamono.num[0] ); }

nanaka2223
質問者

補足

<<ちなみにkuda()内でやっているのは初期化ではなく代入です。 そう言えばそうですね どうも初期化と初期値を代入することを言い分けていませんね。 わかりずらい言い方をしてすみませんでした。 <<前回( http://oshiete.goo.ne.jp/qa/7992723.html )のとこでの理解がいまいちな状態で閉じられてしまいましたからねぇ……。 ポンイタとか関係ないかと。 え、あれからポインタを渡して値を受け渡ししてるのですが関係ないのですか? ただ、ポインタを渡しまくった結果、10個以上ポインタを渡してる状態でして非常に見辛くなって困ってはいますけどね。 さらに増えるみたいなのでややこしいなとは思えていましたが <<それとは別に、「main.cppにとってkudamonoやkudamonが不明な状態」は代わりありません。 宣言もなにもされていないのですからコンパイルエラーになっているはずですが…。 おかしいですね私の環境ではコンパイルエラーになっていないみたいですが <<で、kudamonoやkudamonは「kudamono.cppにあるグローバル変数」なのですから、kuda()で値を代入するのに呼び出し元からアドレスを渡す必要はありません。 それをすると逆に不明な状態になりませんか? 私の開発環境は現在 windows xp Visual C++ 2008なのですが環境によって左右するとか起こりますか?

全文を見る
すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

「構造体をポインタにする」ってのが分からんなぁ. 「アドレスがほしい」ってこと?

nanaka2223
質問者

お礼

NO6からの続きです。 宣言と共に初期値を入れることをやめた場合何とかファイルを2つに分けてもできるようになりました --- main.cpp の内容 --- #include <stdio.h> struct kudamono{ char *name; int num; }; void syoki( struct kudamono *deta ,int i ); int main(void) { int i; struct kudamono deta[5]; for(i=0;i<5;i++){ syoki(&deta[i],i); } for(i=0;i<5;i++){ printf( "%sが%d個ある\n", deta[i].name , deta[i].num ); } return 0; } --- kudamono.cpp の内容 --- #include <stdio.h> struct kudamono{ char *name; int num; }; void syoki( struct kudamono *deta ,int i ) { switch( i ) { case 0: deta->name ="りんご"; deta->num = 1; break; case 1: deta->name ="みかん"; deta->num = 3; break; case 2: deta->name ="オレンジ"; deta->num = 5; break; case 3: deta->name ="もも"; deta->num = 2; break; case 4: deta->name ="キウイ"; deta->num = 4; break; } } 改良しないといけないためもう少し粘ってみます

nanaka2223
質問者

補足

ええっと、以前の話では別のファイルの値をポインタを渡すことによって共有化する方法について教わったのです。 そのため今回も構造体自体をポインタで渡して別のファイルの値を取得することが望ましいと思うのですが、ポインタに渡す方法がわかっていなかったってことですね

全文を見る
すると、全ての回答が全文表示されます。
  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.2

>メンバにstatic int型 の配列を加えようとするとうまくいきませんでした 具体的にどう書いて、どううまくいきませんでしたか? # ってのを書かないと、無駄なやりとりとか増えるんですけどね…。 static const struct{  char name[9];  int num; } kudamono [ ] = {  {"りんご", 1},  {"みかん", 3},  {"オレンジ", 5},  {"もも", 2},  {"キウイ", 4} }; とかでしょうか? あと…質問に掲示した例ではコンパイルエラーになるかと。 main.cppにとってはkudamonoやkudamonがなにものなのか不明ですし、 kudamono.cppにとってもkudamonがなにものか不明です。 # kudamonoとkudamonは、コピペ時のミスでしょうけどね。 # main()からkuda()も呼ばれていません(前に指摘されたはずですが)し…。

nanaka2223
質問者

お礼

<<# main()からkuda()も呼ばれていません(前に指摘されたはずですが)し…。 すみません この部分は構造体をポインタにする方法がわからなかったものでかけませんでした

nanaka2223
質問者

補足

すみませんあれからいろいろ試行錯誤してできるようになりました static struct{  const char *name;  int num; } kudamono [5] = {  {"りんご", 1},  {"みかん", 3},  {"オレンジ", 5},  {"もも", 2},  {"キウイ", 4} }; このような感じになりましたが問題ありますか?

全文を見る
すると、全ての回答が全文表示されます。
  • hashioogi
  • ベストアンサー率25% (102/404)
回答No.1

色々と勘違いされているようですが、こんな感じでどうでしょうか? static const struct{ char name[9]; char num[5]; } kudamono [ ] = { {"りんご", "1個"}, {"みかん", "3個"}, {"オレンジ", "5個"}, {"もも", "2個"}, {"キウイ", "4個"} } ;

nanaka2223
質問者

お礼

メンバが static const char 型のみなら static const struct{ char name[9]; char num[5]; } kudamono [ ] = { {"りんご", "1個"}, {"みかん", "3個"}, {"オレンジ", "5個"}, {"もも", "2個"}, {"キウイ", "4個"} } ; の教えていただいた方法で書けるみたいですが メンバにstatic int型 の配列を加えようとするとうまくいきませんでした

nanaka2223
質問者

補足

ええっとその場合、配列じゃないものが構造体のメンバーにもある場合はどのように書くのでしょうか? } kudamono [ ] = { から下の書き方ですね (作っているプログラム上では、そんなことはありえないのですけどね) }kudamono [ ] = { この部分は要素数を指定してもいいのですよね? }kudamono [9] = { このような感じで

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 文字列をうまく返してくれない

    数値を文字列として呼び出し元に渡し、呼び出し元で文字列を数値に変えようとしたのですがatoi関数(strtolを使うと最初の文字のみ帰ってくるため2桁以上の数値に対応できない)を使うとうまく行きませんでした。 どのように変更したらatoiが使える文字列になりますか? #include <stdio.h> #include <stdlib.h> static struct{   char *name; }kuda[5]={   { "もも" , "りんご" , "みかん" , "バナナ" , "パイナップル" } } char *re_3( void ){   int a = 3;   char str_h[100];   char *str;   sprintf_s( str_h , 100 , "%d" , a );   *str = *str_h; //原因はおそらくここ   return str; } void main( void ){   printf( "%s" , kuda[ atoi( re_3() ) ].name ); }

  • 構造体とfscanf

    ファイルをfscanfを使って文字列を構造体に格納して読み込みたいのですが読み込み方の記述方法がわか りません。 どのようにしたら読み込めますか? 以下ソース ---ソース--- #include <stdio.h> #include <string.h> #include <stdlib.h> struct info //1回目の呼び出し方法 { char name[20]; char mb[20]; }deta; struct info2 //2回目の呼び出し方法 { char *name; char *mb; }deta2; struct info3 //3回目の呼び出し方法 { char *name[6]; char *mb[6]; }deta3; void main(void){ FILE *fp; fp=fopen("yasa.txt","r+"); while( !feof( fp ) ){ fscanf( fp, "%s %s",deta.name,deta.mb ); printf("%s %s\n",deta.name,deta.mb); } rewind( fp ); //2回目の呼び出し方法での記述の仕方がわからない rewind( fp ); //3回目の呼び出し方法での記述の仕方がわからない fclose(fp); } ---yasa.txtの内容--- オレンジ ● みかん ● いちご × もも ● ぶどう × キウイ ●

  • 構造体メンバ及び、strncpy()について

    /* 構造体のメンバを char name[30]; にした時は実行できますが、char *name; としたときはプログラムを実行できません。 コンパイルエラーはともに出ないのですが、strncpy();の使い方が間違っているのか、先に構造体側でメモリサイズを確保しないと、使えないのか? メンバをポインタで持たせた構造体を初期化する関数の作り方を教えてください。 よろしくお願いします。 */ #include <stdio.h> #include <string.h> typedef struct{ char *name; int no; }ST; void set_name(ST *st, char *name, int no); int main(void) { ST st; set_name(&st, "テスト", 1); printf("%s No%d\n", st.name, st.no); return 0; } void set_name(ST *st, char *name, int no) { strncpy(st->name, name, 30); st->no=no; }

  • ポインタ型配列のポインタを構造体のポインタ変数に格納する方法教えて!

    問題の箇所を試行錯誤しても「移植性のないポインタ変換(関数 main )」と表示されます。 どうすればエラーが出ないでしょうか? 返答のほどよろしくお願いいたします。 #include<stdio.h> char *name[] = {"AAA", "BBB", "CCC"}; struct namelist{ char *name; struct namelist *next; }*head; void main(void) { printf("name = %s\n", name[1]); head -> name = *name[1];←問題の箇所 printf("head -> name = %s\n", head -> name); }

  • 構造体宣言したポインタ変数に値を代入するには?

    strcpy(p -> key ,name);と打ってp -> key に入力した名前を格納したいのですがうまくいきません。 ほかにもp -> key = nameなども試してみましたがコンパイルエラーが出現してダメでした。 うまく格納できるやり方があれば教えてください。よろしくお願いします。 #include<stdio.h> #include<string.h> #define WORD_LENGTH 50 /* 文字列の最大長 */ typedef struct cell{ char key[WORD_LENGTH]; struct cell *next; /* 次のセルへのポインタ */ } CELL; void main(void) { char name[WORD_LENGTH]; CELL *p; printf("名前入力\n"); scanf("%s\n", name); strcpy(p -> key ,name); printf("%s\n", p -> key); }

  • 分割コンパイルの方法がわかりません‥(Studio.NET)

    mainとsubという2つのcppファイルと各ヘッダファイルで分割コンパイルを試みましたがうまくいきません・・。 何が間違っているのでしょう・・。 エラーメッセージ error LNK2005: "char * a" (?a@@3PADA)は既にmain.objで定義されています。 fatal error LNK1169: 1つ以上の複数回定義されているシンボルが見つかりました。 と表示されます。ファイルソースは以下です。どなたか教えてください>< ----------(main.h)---------- char a[100]; ----------(main.cpp)---------- #include<stdio.h> #include "main.h" #include "sub.h" int main(){  sprintf(a,"hello.");  sub_write();  return 0; } -----------(sub.h)----------- void sub_write(); -----------(sub.cpp)------------- #include <stdio.h> #include "main.h" #include "sub.h" void sab(){  printf("%s\n",a); } return; }

  • 配列について

    初歩的な質問ですいませんが、質問よろしくお願いします。 ◎1----------------------------- #include<stdio.h> int main(void) { char ss[10]="AB"; printf("ss=%s\n",ss); return 0; } ------------------------------------ ◎2-------------------------------- #include<stdio.h> int main(void) { char ss[10]; ss[0]='A'; ss[1]='B'; ss[2]=0; printf("ss=%s\n",ss); return 0; } ----------------------------------- ◎3------------------------------- #include<stdio.h> #include<string.h> int main(void) { char ss[10]; strcpy(ss,"AB"); printf("ss=%s\n",ss); return 0; } ----------------------------------- ◎4------------------------------- #include<stdio.h> int main(void) { char ss[10]; ss="AB"; printf("ss=%s\n",ss); return 0; } ---------------------------------- 以上4つのプログラムで、◎2と◎3は正常に動くと理解できたのですが、何故、◎1は正常に動き、◎4は「'const char [3]' から 'char [10]' に変換できません。」といったようなエラーが出てしまうか分かりません。 教えていただければ嬉しいです。

  • 構造体?

    以下は、あるC++のサンプルプログラムの頭の部分なのですが、構造体associateの中に、再びassociateが2回も出てきます。何をしている記述なのか教えてください。 #include <vector> #include <algorithm> #include <functional> #include <iostream> using namespace std; struct associate { int num; char chr; associate(int n, char c) : num(n), chr(c) {};←この業は何? associate() : num(0), chr('\0'){};←この行は何? }; bool operator<(const associate &x, const associate &y) { return x.num < y.num; } ostream& operator<<(ostream &s, const associate &x) { return s << "<" << x.num << ";" << x.chr << ">"; } int main () { vector<associate>::iterator i, j, k; associate arr[20] = {associate(-4, ' '), associate(16, ' '), ・ ・ ・ associate(-3, 'e'), associate(15, ' ')};

  • 構造体とポインタについて教えてください。

    #include <stdio.h> typedef struct ningen { char *name; char *sex; int age; } NINGEN; NINGEN data = {"牧村 五郎",NULL,30}; char mf[2][3] = {"男","女"}; void main(void) { data.sex=mf[0]; printf("%s (%s) %d歳\n", data.name, data.sex, data.age); } このプログラムで実行結果は 牧村 五郎 (男) 30歳 となるのですが、最初の typedef struct ningen { char *name; char *sex; int age; } NINGEN; のところで、nameとsexはアドレスで宣言しているので printf("%s (%s) %d歳\n", data.naem, data.sex, data.age);でのdata.naem, data.sexでの対象もアドレスを示していると思うのですが、 結果は値を表示しているのはなぜでしょうか?

  • 構造体の動的メモリについて

    #include <stdio.h> #include <stdlib.h> #include <string.h> #define NUM 10 /*生徒数*/ typedef struct data { int num; /*従業員番号*/ char name[16]; /*名前*/ int jap; /*国語の点数*/ int math; /*数学の点数*/ }data; int main(void) { data test[NUM]; /*生徒のデータ*/ FILE *fp; /*ファイル操作用*/ int i; /*配列インデックス*/ int count; /*データ分割用*/ char s[100]; /*データ読み込み用*/ char *token; /*データ分割用*/ char *data[6]; /*分割データ保存用*/ fp = fopen ("data1.txt","r");        for (i=0; i<NUM; i++){ fgets (s, sizeof(s), fp); /*dataファイルから1行読み込み*/ token = strtok(s, ","); /*読み込んだデータを","で分割する*/ count=0; while (token != NULL){ data[count] = token; /*分割したデータを配列へ入れる*/ token = strtok(NULL,","); count++; } test[i].num = atoi(data[0]);       strcpy (test[i].name, data[1]); test[i].jap = atoi(data[2]); test[i].math = atoi(data[3]); } fclose(fp);       } このプログラムを構造体へのポインタの配列で管理するように変えたいのですが、どのように変更すればいいのでしょうか。 条件として、個人データを格納するメモリ領域とポインタの配列のメモリ領域は動的に確保します。 初心者でよくわからないので詳しく教えていただけると助かります。よろしくお願いします。