![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
構造体をポインターに入れたいのですがうまくいきません
どうしたら入れることができますか?
―――ソース―――
struct str{
char *name;
};
static struct str state_ab[60][4] = {
{ { { "いちご" } } , { { "みかん" } } ,{ { "レモン" } } , { { "ブドウ" } } },
{ { { "" } } , { { "" } } ,{ { "" } } , { { "" } } },
};
static struct str state_ab2[60][8] = {
{ { { "きゅうり" } } , { { "セロリ" } } ,{ { "じゃがいも" } } , { { "にんじん" } } , { { "たまねぎ" } } , { { "ニンニク" } } ,{ { "レタス" } } , { { "キャベツ" } } },
{ { { "" } } , { { "" } } ,{ { "" } } , { { "" } } , { { "" } } , { { "" } } ,{ { "" } } , { { "" } } },
};
static struct str state_ab3[60][4] = {
{ { { "牛肉" } } , { { "豚肉" } } ,{ { "鶏肉" } } , { { "魚肉" } } },
{ { { "" } } , { { "" } } ,{ { "" } } , { { "" } } },
};
char *state_ab_f_read( int mode , int num1 , int num2 ){
struct str *p;
switch( mode ){
case 0: p = state_ab; break;
case 1: p = state_ab2; break;
case 2: p = state_ab3; break;
}
return p[ num1 ][ num2 ].name;
}
―――エラー内容―――
c:\documents and settings\user\my documents\visual studio 2008\projects\kami\state_ab_fd.cpp(237) : error C2440: '=' : 'str [60][4]' から 'str *' に変換できません。
指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。
c:\documents and settings\user\my documents\visual studio 2008\projects\kami\state_ab_fd.cpp(238) : error C2440: '=' : 'str [60][8]' から 'str *' に変換できません。
指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。
c:\documents and settings\user\my documents\visual studio 2008\projects\kami\state_ab_fd.cpp(239) : error C2440: '=' : 'str [60][4]' から 'str *' に変換できません。
指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。
c:\documents and settings\user\my documents\visual studio 2008\projects\kami\state_ab_fd.cpp(241) : error C2676: 二項演算子 '[' : 'str' は、この演算子または定義済の演算子に適切な型への変換の定義を行いません。(新しい動作; ヘルプを参照)
c:\documents and settings\user\my documents\visual studio 2008\projects\kami\state_ab_fd.cpp(241) : error C2228: '.name' の左側はクラス、構造体、共用体でなければなりません
ビルドログは "file://c:\Documents and Settings\USER\My Documents\Visual Studio 2008\Projects\kami\Debug\BuildLog.htm" に保存されました。
A 回答 (7件)
- 最新から表示
- 回答順に表示
No.7
- 回答日時:
// たびたび王次郎です
struct str{
char *name[2] ;
} ;
static struct str state_ab[4] = {
{ "いちご" , "" } ,
{ "みかん" , "" } ,
{ "レモン" , "" } ,
{ "ブドウ" , "" } ,
} ;
static struct str state_ab2[8] = {
{ "きゅうり" , "" } ,
{ "セロリ" , "" } ,
{ "じゃがいも" , "" } ,
{ "にんじん" , "" } ,
{ "たまねぎ" , "" } ,
{ "ニンニク" , "" } ,
{ "レタス" , "" } ,
{ "キャベツ" , "" } ,
} ;
static struct str state_ab3[4] = {
{ "牛肉" , "" } ,
{ "豚肉" , "" } ,
{ "鶏肉" , "" } ,
{ "魚肉" , "" } ,
} ;
// その1:str配列の先頭アドレスをpに渡す
char *state_ab_f_read_1( int mode , int num1 , int num2 ){
struct str *p=NULL ;
switch( mode ){
case 0: p = state_ab ; break;
case 1: p = state_ab2 ; break;
case 2: p = state_ab3 ; break;
}
return p[num1].name[num2] ;
}
// その2:strのアドレスをpに渡す
char *state_ab_f_read_2( int mode , int num1 , int num2 ){
struct str *p=NULL ;
switch( mode ){
case 0: p = &state_ab[num1] ; break;
case 1: p = &state_ab2[num1] ; break;
case 2: p = &state_ab3[num1] ; break;
}
return p->name[num2] ;
}
// もし、num1 と num2 の使い方が逆の場合は入れ替えてください
// 以上
No.6
- 回答日時:
毎度、王次郎です
これでいかがでしょうか?
C++でなければ(classが嫌なら)、構造体と初期化関数にすれば同じことができますが、
その場合は構造体を使うメリットがないと思いますが。
構造体というのは、メモリ上のデータ構造を規定しておく構文なので、
配列が60なのか80なのか事前に決めなくてはいけません。
下の回答の例では、構造体(というかclass)の宣言でchar型の2階のポインタを
メモリ上に確保しておいて、実際の配列はコンストラクタ内で確保しています。
classを使うことのメリットは、コンストラクタ(str::str)でメモリ確保の仕方を定義できる
点にあります。そしてデストラクタ(str::~str)で変数を使い終わったときのメモリの開放を
自動的に行えます。
//---------------------------------------------------------------------------
#include <string.h>
class str
{
public :
str( char *strA , char *strB , int nSize ) ;
~str( ) ;
char **p ;
} ;
str::str( char *strA , char *strB , int nSize )
{
p = new char*[2] ;
p[0] = new char[nSize] ;
p[1] = new char[nSize] ;
strcpy( p[0] , strA ) ;
strcpy( p[1] , strB ) ;
}
str::~str( )
{
delete[] p[0] ;
delete[] p[1] ;
delete[] p ;
}
class str state_ab[4] = {
str( "いちご" , "" , 60 ) ,
str( "みかん" , "" , 60 ) ,
str( "レモン" , "" , 60 ) ,
str( "ブドウ" , "" , 60 ) ,
} ;
static str state_ab2[8] = {
str( "きゅうり" , "" , 80 ) ,
str( "セロリ" , "" , 80 ) ,
str( "じゃがいも" , "" , 80 ) ,
str( "にんじん" , "" , 80 ) ,
str( "たまねぎ" , "" , 80 ) ,
str( "ニンニク" , "" , 80 ) ,
str( "レタス" , "" , 80 ) ,
str( "キャベツ" , "" , 80 ) ,
} ;
static str state_ab3[4] = {
str( "牛肉" , "" , 60 ) ,
str( "豚肉" , "" , 60 ) ,
str( "鶏肉" , "" , 60 ) ,
str( "魚肉" , "" , 60 ) ,
} ;
char *state_ab_f_read( int mode , int num1 , int num2 )
{
class str *s=NULL ;
switch( mode ){
case 0: s = state_ab ; break;
case 1: s = state_ab2; break;
case 2: s = state_ab3; break;
}
if( s == NULL ) {
return NULL ;
}
return s[ num1 ].p[ num2 ] ;
}
![「構造体をポインターに入れたい」の回答画像6](http://oshiete.xgoo.jp/_/bucket/oshietegoo/images/media/1/523682743_5497ecc683ddf/M.jpg)
No.5
- 回答日時:
#1です。
ちょっと落ち着いて、コードを書いてみました。構造体の中の文字列はこちらのデバッグ環境の都合で変更しましたので、適当に中身を変えてください。
structstr {
char *name;
};
struct str state_ab[60][4] = {
{ "A001", "A002", "A003", "A004" },
{ "", "", "", "" }
};
struct str state_ab2[60][8] = {
{ "B001", "B002", "B003", "B004", "B005", "B006", "B007", "B008"},
{ "", "", "", "", "", "", "", "" }
};
struct str state_ab3[60][8] = {
{ "C001", "C002", "C003", "C004", "C005", "C006", "C007", "C008" },
{ "", "", "", "", "", "", "", "" }
};
struct str* state_ab_f_read( int mode, int num1, int num2 ) {
struct str *p;
switch( mode ) {
case 0: p = &state_ab[num1][num2];
break;
case 1: p = &state_ab2[num1][num2];
break;
case 2: p = &state_ab3[num1][num2];
break;
defualt:
p = (struct str*)NULL;
}
return( p );
}
多元の構造体の異なる次元なので、関数の受けは、単に str* として、下記の様なmain から呼び出してみたら、一応表示はされました。
void main( void ) {
int mode, num1, num2;
while( 1 ) {
printf( "mode = ?" );
scanf( "%d", &mode );
if ( mode > 2 ) break;
printf( "num1 = ?" );
scanf("%d",&num1 );
printf( "num2 = ?");
scanf("%d",&num2);
printf(" %s\n",state_ab_f_read( mode, num1, num2 )->name );
}
return 0;
}
付け焼刃で作ったので、あまり綺麗ではないですが、参考にしてみてください。
No.4
- 回答日時:
struct str state_ab[60][4]
は
「str[4]型」 の1次元配列 state_ab
static struct str state_ab2[60][8]
は
「str[8]型」 の1次元配列 state_ab2
と見做すことができます。
「str[4]型」と「str[8]型」が違うので、単純に同じポインタを使うことができません。
解決の一つは、後ろの[4]、[8]等を同じにすることです。
数が少なければ御自身で書かれた
> switch( mode ){
> case 0: return state_ab[ num1 ][ num2 ].name; break;
> case 1: return state_ab2[ num1 ][ num2 ].name; break;
> case 2: return state_ab3[ num1 ][ num2 ].name; break;
> }
> return NULL;
でもよいでしょう。
他には、「strの配列やリスト へのポインタ」の配列(やリスト) にする、というのもあります。
メモリ管理や初期化が少し面倒ですが。
No.3
- 回答日時:
struct str{
char name[2][60] ;
} ;
static struct str state_ab[4] = {
{ "いちご" , "" } ,
{ "みかん" , "" } ,
{ "レモン" , "" } ,
{ "ブドウ" , "" } ,
} ;
static struct str state_ab2[8] = {
{ "きゅうり" , "" } ,
{ "セロリ" , "" } ,
{ "じゃがいも" , "" } ,
{ "にんじん" , "" } ,
{ "たまねぎ" , "" } ,
{ "ニンニク" , "" } ,
{ "レタス" , "" } ,
{ "キャベツ" , "" } ,
} ;
static struct str state_ab3[4] = {
{ "牛肉" , "" } ,
{ "豚肉" , "" } ,
{ "鶏肉" , "" } ,
{ "魚肉" , "" } ,
} ;
char *state_ab_f_read( int mode , int num1 , int num2 ){
struct str *p=NULL ;
switch( mode ){
case 0: p = state_ab ; break;
case 1: p = state_ab2; break;
case 2: p = state_ab3; break;
}
return p[ num1 ].name[num2] ;
}
この回答への補足
皆さんの意見を参考に色々試してみたのですが、できませんでした。
NO3さんの書き方だと
がstate_ab と state_ab2 と state_ab3がそれぞれ60ないとだめで、state_ab2が80だった場合の応用が効きません。
この応用部分の書き方を試してみてみたのですがうまく行きませんでした
NO2さんの参照先をいじってみてもNO2さんが言ったとおりでできませんでした
回答ありがとうございます。
一文字ずつ入れる文字列の場合、最初にNULLを入れるのですね。
最初見たところ何故NULLを入れるのかわかりませんでした。
No.2
- 回答日時:
(1) 初期化時の{}が多すぎます。
以下でいいです。
static struct str state_ab[60][4] = {
{
{"いちご" },
{ "みかん" },
{ "レモン" },
{ "ブドウ" }
},
{
{ "" },
{ "" },
{ "" },
{ "" }
},
};
(2) ポインタへの代入
関数state_ab_f_read()内でポインタpにstate_ab、state_ab2、state_ab3を代入していますけど、これはできません。pが一次元配列のアドレスしか代入できないからです。
二次元配列用のポインタも定義できますけど、今回は[60][4]と[60][8]の2種類ありますので使用できません。
多次元配列のポインタに関しては以下を参照。
http://questionbox.jp.msn.com/qa8571161.html
この回答への補足
構造体をポインターに入れることが不可能ならこれが正解でよろしいですか?
struct str{
char *name;
};
static struct str state_ab[60][4] = {
{ { "いちご" }, { "みかん" }, { "レモン" }, { "ブドウ" } },
{ { "" } , { "" } , { "" } , { "" } }
};
static struct str state_ab2[60][8] = {
{ { "きゅうり" } , { "セロリ" } , { "じゃがいも" }, { "にんじん" }, { "たまねぎ" }, { "ニンニク" }, { "レタス" }, { "キャベツ" } },
{ { "" } , { "" } , { "" } , { "" } , { "" } , { "" } , { "" } , { "" } }
};
static struct str state_ab3[60][4] = {
{ { "牛肉" }, { "豚肉" }, { "鶏肉" }, { "魚肉" } },
{ { "" } , { "" } , { "" } , { "" } }
};
char *state_ab_f_read( int mode , int num1 , int num2 ){
switch( mode ){
case 0: return state_ab[ num1 ][ num2 ].name; break;
case 1: return state_ab2[ num1 ][ num2 ].name; break;
case 2: return state_ab3[ num1 ][ num2 ].name; break;
}
return NULL;
}
回答ありがとうございます
<初期化時の{}が多すぎます。
それは私も書いている時に思いました。
修正してみます。
<二次元配列用のポインタも定義できますけど、今回は[60][4]と[60][8]の2種類ありますので使用できません。
今回も一時配列用でもできると思ったのですが、実はこれは多次配列なのですね
No.1
- 回答日時:
なぜこの構造体の定義が必要なのか不明ですが、取り急ぎ、エラーについて下記を試してみてください。
struct str *p これを struct str **p
return p[ num1 ][ num2 ].name を return p[ num1 ][ num2 ]->name
コンパイルを試してないので、エラーかワーニングが出るかも知れないですが、いずれにしても、
変数の引渡しには、代入する側とされる側は同じ定義でないとならないことと、
配列とポインターの関係
構造体のポインター参照(アロー参照)
の辺りを参考書(K&Rでも、はじめてのCでも)などで良く読んで、修正して行ってみてください。
この例題自体には、構造体ポインターを無理やり使う理由はないと思うので、恐らく、リスト構造をポインター渡しする手法を勉強中なのだと理解します。構造体ポインター以前に、配列とポインターの関係、多元配列とポインターの関係が理解出来ていないと、構造体で大混乱します。
あと、初歩的なことですが構造体ポインタの参照は -> アロー演算子を使います。
ご参考に。
回答ありがとうございます
方法を試したのですが以下のようなエラーが出ます。
c:\documents and settings\user\my documents\visual studio 2008\projects\kami\state_ab_fd.cpp(239) : error C2440: '=' : 'str [110][4]' から 'str **' に変換できません。
指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。
c:\documents and settings\user\my documents\visual studio 2008\projects\kami\state_ab_fd.cpp(240) : error C2440: '=' : 'str [50][8]' から 'str **' に変換できません。
指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。
c:\documents and settings\user\my documents\visual studio 2008\projects\kami\state_ab_fd.cpp(241) : error C2440: '=' : 'str [60][4]' から 'str **' に変換できません。
指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。
c:\documents and settings\user\my documents\visual studio 2008\projects\kami\state_ab_fd.cpp(243) : error C2819: クラス 'str' にはオーバーロードされたメンバ 'operator ->' がありません。
c:\documents and settings\user\my documents\visual studio 2008\projects\kami\state_ab_fd.cpp(4) : 'str' の宣言を確認してください。
代わりに '.' を使用しますか?
c:\documents and settings\user\my documents\visual studio 2008\projects\kami\state_ab_fd.cpp(243) : error C2232: '->str::name' : 左のオペランドが 'struct' 型です。'.' を使用してください。
なぜこの構造体の定義が必要なのかは、他にもこの構造体を使っているため似たような感じにしたかったからです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# int tff(int clk) { static int state = 0; //状態 stat 1 2022/07/11 21:14
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- その他(プログラミング・Web制作) Arduinoに関する質問 4 2023/08/07 21:19
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
- その他(プログラミング・Web制作) python fbprophetについて 1 2022/09/29 19:44
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
関数から配列を返すには?
-
構造体のextern方法
-
配列の要素数に変数を入れたい...
-
AfxBeginThread の引数について
-
define で 配列
-
C#で構造体の配列を持った構造...
-
MFCのCArrayを使った二次元配列
-
10人分の生徒の英語の点数{32,3...
-
.NET C++で、構造体の配列をnew...
-
c言語の自分で数字を入力してサ...
-
C言語で質問です
-
C言語において、 配列要素をひ...
-
C言語で重複組合せを全列挙
-
C#でのフィボナッチ数列
-
構造体の動的確保について
-
int i, int i[1];
-
別ファイルの構造体の値を読み...
-
C++DLLからC#へのコールバック...
-
構造体をポインターに入れたい
-
背景差分法における正規化距離
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
関数から配列を返すには?
-
C言語において、 配列要素をひ...
-
配列の要素数に変数を入れたい...
-
構造体のextern方法
-
define で 配列
-
c言語
-
C#で構造体の配列を持った構造...
-
C言語の2次元配列 容量が大き...
-
c言語 構造体
-
C言語 ファイルの指定された行...
-
C言語についてです 5人のテスト...
-
int i, int i[1];
-
fclose()でセグメンテーション違反
-
char型配列をint型に代入するには
-
C言語から質問です。
-
Cのエラー
-
コンボボックスでデフォルト値...
-
C言語の課題が出たのですが自力...
-
MFCのCArrayを使った二次元配列
-
[C++]const int と配列
おすすめ情報