電子書籍の厳選無料作品が豊富!

構造体をポインターに入れたいのですがうまくいきません
どうしたら入れることができますか?

―――ソース―――
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件)

// たびたび王次郎です



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 の使い方が逆の場合は入れ替えてください
// 以上
    • good
    • 0

毎度、王次郎です


これでいかがでしょうか?
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
    • good
    • 0

#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;
}


付け焼刃で作ったので、あまり綺麗ではないですが、参考にしてみてください。
    • good
    • 0

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の配列やリスト へのポインタ」の配列(やリスト) にする、というのもあります。
メモリ管理や初期化が少し面倒ですが。
    • good
    • 0

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さんが言ったとおりでできませんでした

補足日時:2014/09/26 16:53
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
一文字ずつ入れる文字列の場合、最初にNULLを入れるのですね。
最初見たところ何故NULLを入れるのかわかりませんでした。

お礼日時:2014/09/26 15:45

(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;
}

補足日時:2014/09/26 17:20
    • good
    • 0
この回答へのお礼

回答ありがとうございます
<初期化時の{}が多すぎます。
それは私も書いている時に思いました。
修正してみます。

<二次元配列用のポインタも定義できますけど、今回は[60][4]と[60][8]の2種類ありますので使用できません。
今回も一時配列用でもできると思ったのですが、実はこれは多次配列なのですね

お礼日時:2014/09/26 15:51

なぜこの構造体の定義が必要なのか不明ですが、取り急ぎ、エラーについて下記を試してみてください。



struct str *p これを  struct str **p

return p[ num1 ][ num2 ].name を    return p[ num1 ][ num2 ]->name

コンパイルを試してないので、エラーかワーニングが出るかも知れないですが、いずれにしても、

変数の引渡しには、代入する側とされる側は同じ定義でないとならないことと、

配列とポインターの関係
構造体のポインター参照(アロー参照)

の辺りを参考書(K&Rでも、はじめてのCでも)などで良く読んで、修正して行ってみてください。

この例題自体には、構造体ポインターを無理やり使う理由はないと思うので、恐らく、リスト構造をポインター渡しする手法を勉強中なのだと理解します。構造体ポインター以前に、配列とポインターの関係、多元配列とポインターの関係が理解出来ていないと、構造体で大混乱します。
あと、初歩的なことですが構造体ポインタの参照は -> アロー演算子を使います。

ご参考に。
    • good
    • 0
この回答へのお礼

回答ありがとうございます
方法を試したのですが以下のようなエラーが出ます。
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' 型です。'.' を使用してください。

なぜこの構造体の定義が必要なのかは、他にもこの構造体を使っているため似たような感じにしたかったからです。

お礼日時:2014/09/26 15:59

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!