こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

構造体の変数の値を、動的に取得する方法を教えてください

C言語で、構造体の変数の値を取得したいのですが、その際、
他の変数に格納してある文字列を元に動的に行いたいのですが、可能でしょうか?

イメージとしては、
struct Entry{
char name[20];
char address[80];
char email[40];
};
struct Entry data;
strcpy(data.name, "Taro");
strcpy(data.address, "Tokyo");
strcpy(data.email, "taro@taro");

char var_name[20];
strcpy(var_name, "email");

printf("%s", data.var_name);
↑この行の構造体の変数へのアクセス方法が間違っているのはわかっていますが、このような時に「taro@taro」と出力させたいのです。

var_nameの値を「name, address, email」に換える事により「Taro, Tokyo, taro@taro」と出力を切り換えたいと思っています。

普段は他の言語をよく使用しており、そちらではこの手法を時々使っていたのですが、C言語でも出来ないものかと思っております。

よろしくお願いします。

投稿日時 - 2007-08-09 12:08:28

QNo.3240755

困ってます

質問者が選んだベストアンサー

既に多数出ていますが、
そもそもC言語では関数名や手続きなどはプロジェクト内、
またはファイル内において一意で認識される名前である必要が
あるため「同名で」「別の手続き」というのは、
そもそものC言語での考え方では厳しいといえると思います。

それっぽくC言語での例だと
こんな感じになると思います。
(インデントは全角スペースなのでコンパイルには注意)
#include <stdio.h>
#include <string.h>

#define MAXBUFFERLEN (80)

/* varメンバの擬似連想配列に対する列挙指定子 */
enum{
 name = 0,
 email,
 address,
 
 /* ここに指定子を追加することで、 *
  * 構造体メンバの配列も大きくなっていく */
 age, //例えば年齢を追加。(ただし扱いは文字列)

 MAXVARELEMENT,
};

/* 構造体にこだわるなら */
struct Entry{
 char var[MAXVARELEMENT][MAXBUFFERLEN];
};

int main( void )
{
 struct Entry data;
 strcpy(data.var[name], "Taro");
 strcpy(data.var[address], "Tokyo");
 strcpy(data.var[email], "taro@taro");
 strcpy(data.var[age], "20");

 printf( "%s\n", data.var[name] );
 printf( "%s\n", data.var[address] );
 printf( "%s\n", data.var[email] );
 printf( "%s\n", data.var[age] );
 return 0;
}

投稿日時 - 2007-08-09 14:56:59

お礼

回答して頂いた皆様、ありがとうございます。

今回の質問は、C言語をよりよく理解するのに役に立ちました。
ありがとうございました。

投稿日時 - 2007-08-10 01:35:19

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(6)

ANo.5

> この文章は、他の言語であれば動的に構造体の変数(もしくはクラスのプロパティ)にアクセスするのはOKだが、C言語の場合はそのような手法は良くないと言う意味でしょうか?

大体そんなところです。

> 私がこれまでに読んだ書籍では「動的にアクセスする方が効率が良くなる」と紹介しているものが多く、なぜ「効率が悪くなる」のか分からないのですが。

言語にもよりますが、動的な扱いに特化して設計・実装されている言語の場合、無理に静的に行おうとするとかえって効率が悪くなる可能性はあります。
しかし、コンピュータの一般論からすれば、静的に処理した方が実行時の効率はよくなります。

> 動的という意味では、オブジェクト指向のPolymorphismも抽象度の高い変換形式を実現できる方法として、有益であると思っています。

ポリモフィズムを実現するのは、必ずしも動的である必要はありません。
C言語ではちょっと厳しいですが、C++であれば、静的なポリモフィズムを実現するためにテンプレートメタプログラミングを使うのは普通のことです。

投稿日時 - 2007-08-09 14:07:45

ANo.4

そもそも、文字列として格納されている変数名でアクセスすることは、
たとえそれが可能な言語でも、なるべくやめたほうがいいですよ。
ものすごく読みにくくて、何やってるのかちょっと時間がたつと自分でもわからなくなる可能性が大です。昔敵視されてたgotoなんかより、ずっとタチ悪いと思います。
いわゆるeval関数というのは、たしかに超強力ですけど、その分、弊害も強力です。

変数名というのは、あくまで、プログラム中に使う仮の名前であって、本来であれば、例えばプログラム中の「a」という名前の変数を全て「b」に置換しても、正常に動くことが期待されています。この大前提を破るようなプログラムは極力避けるべきです。

eval関数と、オブジェクト指向のポリモーフィズムは、全く別の話です。

投稿日時 - 2007-08-09 14:07:14

ANo.3

> 「効率が悪くなる」というのは具体的にはどのような意味でしょうか?

プログラムサイズが大きく、実行速度が低下します。

また、C言語の場合には自分で実装しなければいけないわけですから、それだけプログラムが複雑になり、開発効率も保守効率も低下します。
結果として、それだけ費用が多く発生し、品質・信頼性が低下します(品質・信頼性の低下を防ぐには、さらに費用がかかります)。
これはC言語だから悪いのではなく、C言語にふさわしくない設計に問題があります。

投稿日時 - 2007-08-09 13:20:19

お礼

ご回答ありがとうございます。

> これはC言語だから悪いのではなく、C言語にふさわしくない設計に問題があります。

この文章は、他の言語であれば動的に構造体の変数(もしくはクラスのプロパティ)にアクセスするのはOKだが、C言語の場合はそのような手法は良くないと言う意味でしょうか?

私がこれまでに読んだ書籍では「動的にアクセスする方が効率が良くなる」と紹介しているものが多く、なぜ「効率が悪くなる」のか分からないのですが。
動的という意味では、オブジェクト指向のPolymorphismも抽象度の高い変換形式を実現できる方法として、有益であると思っています。

とりあえず、最後の文章の意味がうまく解釈できなかったので、よろしければ補足していただけますか?

投稿日時 - 2007-08-09 13:40:37

ANo.2

> 普段は他の言語をよく使用しており、そちらではこの手法を時々使っていたのですが、C言語でも出来ないものかと思っております。

この発想が間違っていると思います。
動的に構造体のメンバをアクセスできるようにすると、それだけ効率が悪くなります。
ですから、効率を重視する部分は通常の構造体で、メンバ名等を頼りにアクセスしたいなら連想配列を別途実装した方がよいでしょう。

ちなみに、メンバの指定方法が文字列ではなく、列挙定数でよいのであれば、もっと簡単で、かつ効率を損なうことなく実現する方法があるはずです。
(例えば、構造体ではなく、ポインタ配列を使うなど。)

投稿日時 - 2007-08-09 12:48:49

お礼

> 動的に構造体のメンバをアクセスできるようにすると、それだけ効率が悪くなります。

「効率が悪くなる」というのは具体的にはどのような意味でしょうか?
今回の質問の内容とは離れてしまいますが、今後の参考にしたいと思いますので、教えていただけると助かります。

投稿日時 - 2007-08-09 12:56:28

ANo.1

Cではstructに関数を入れられないので、こんな感じでしょうか?
ちなみにC++ではclassを使います。

struct Entry{
char name[20];
char address[80];
char email[40];
};
struct Entry data;
char *get_data(char *var_name) {
if (strcmp(var_name,"name") return data.name;
if (strcmp(var_name,"address") return data.address;
if (strcmp(var_name,"email") return data.email;
return "";
}

void main() {
strcpy(data.name,"Taro");
strcpy(data.address,"Tokyo");
strcpy(data.email,"taro@taro");

char var_name[20];
strcpy(var_name,"email");
printf("%s",get_data(var_name));
}

投稿日時 - 2007-08-09 12:29:05

お礼

早速ご回答ありがとうございます。

自分のやりたい事に、だいぶ近づいてきました。
if文による条件分岐を使わずにできれば最高なのですが(構造体の変数の数とともに、分岐も増えてしまうので)、可能でしょうか?

投稿日時 - 2007-08-09 12:52:34

あなたにオススメの質問