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言語でも出来ないものかと思っております。
よろしくお願いします。
No.6ベストアンサー
- 回答日時:
既に多数出ていますが、
そもそも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;
}
回答して頂いた皆様、ありがとうございます。
今回の質問は、C言語をよりよく理解するのに役に立ちました。
ありがとうございました。
No.5
- 回答日時:
> この文章は、他の言語であれば動的に構造体の変数(もしくはクラスのプロパティ)にアクセスするのはOKだが、C言語の場合はそのような手法は良くないと言う意味でしょうか?
大体そんなところです。
> 私がこれまでに読んだ書籍では「動的にアクセスする方が効率が良くなる」と紹介しているものが多く、なぜ「効率が悪くなる」のか分からないのですが。
言語にもよりますが、動的な扱いに特化して設計・実装されている言語の場合、無理に静的に行おうとするとかえって効率が悪くなる可能性はあります。
しかし、コンピュータの一般論からすれば、静的に処理した方が実行時の効率はよくなります。
> 動的という意味では、オブジェクト指向のPolymorphismも抽象度の高い変換形式を実現できる方法として、有益であると思っています。
ポリモフィズムを実現するのは、必ずしも動的である必要はありません。
C言語ではちょっと厳しいですが、C++であれば、静的なポリモフィズムを実現するためにテンプレートメタプログラミングを使うのは普通のことです。
No.4
- 回答日時:
そもそも、文字列として格納されている変数名でアクセスすることは、
たとえそれが可能な言語でも、なるべくやめたほうがいいですよ。
ものすごく読みにくくて、何やってるのかちょっと時間がたつと自分でもわからなくなる可能性が大です。昔敵視されてたgotoなんかより、ずっとタチ悪いと思います。
いわゆるeval関数というのは、たしかに超強力ですけど、その分、弊害も強力です。
変数名というのは、あくまで、プログラム中に使う仮の名前であって、本来であれば、例えばプログラム中の「a」という名前の変数を全て「b」に置換しても、正常に動くことが期待されています。この大前提を破るようなプログラムは極力避けるべきです。
eval関数と、オブジェクト指向のポリモーフィズムは、全く別の話です。
No.3
- 回答日時:
> 「効率が悪くなる」というのは具体的にはどのような意味でしょうか?
プログラムサイズが大きく、実行速度が低下します。
また、C言語の場合には自分で実装しなければいけないわけですから、それだけプログラムが複雑になり、開発効率も保守効率も低下します。
結果として、それだけ費用が多く発生し、品質・信頼性が低下します(品質・信頼性の低下を防ぐには、さらに費用がかかります)。
これはC言語だから悪いのではなく、C言語にふさわしくない設計に問題があります。
ご回答ありがとうございます。
> これはC言語だから悪いのではなく、C言語にふさわしくない設計に問題があります。
この文章は、他の言語であれば動的に構造体の変数(もしくはクラスのプロパティ)にアクセスするのはOKだが、C言語の場合はそのような手法は良くないと言う意味でしょうか?
私がこれまでに読んだ書籍では「動的にアクセスする方が効率が良くなる」と紹介しているものが多く、なぜ「効率が悪くなる」のか分からないのですが。
動的という意味では、オブジェクト指向のPolymorphismも抽象度の高い変換形式を実現できる方法として、有益であると思っています。
とりあえず、最後の文章の意味がうまく解釈できなかったので、よろしければ補足していただけますか?
No.2
- 回答日時:
> 普段は他の言語をよく使用しており、そちらではこの手法を時々使っていたのですが、C言語でも出来ないものかと思っております。
この発想が間違っていると思います。
動的に構造体のメンバをアクセスできるようにすると、それだけ効率が悪くなります。
ですから、効率を重視する部分は通常の構造体で、メンバ名等を頼りにアクセスしたいなら連想配列を別途実装した方がよいでしょう。
ちなみに、メンバの指定方法が文字列ではなく、列挙定数でよいのであれば、もっと簡単で、かつ効率を損なうことなく実現する方法があるはずです。
(例えば、構造体ではなく、ポインタ配列を使うなど。)
> 動的に構造体のメンバをアクセスできるようにすると、それだけ効率が悪くなります。
「効率が悪くなる」というのは具体的にはどのような意味でしょうか?
今回の質問の内容とは離れてしまいますが、今後の参考にしたいと思いますので、教えていただけると助かります。
No.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));
}
早速ご回答ありがとうございます。
自分のやりたい事に、だいぶ近づいてきました。
if文による条件分岐を使わずにできれば最高なのですが(構造体の変数の数とともに、分岐も増えてしまうので)、可能でしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
【お題】 ・存在しそうで存在しないモノマネ芸人の名前を教えてください
-
秘密基地、どこに作った?
小さい頃、1度は誰もが作ったであろう秘密基地。 大人の今だからこそ言える、あなたの秘密基地の場所を教えてください!
-
「これはヤバかったな」という遅刻エピソード
寝坊だったり、不測の事態だったり、いずれにしても遅刻の思い出はいつ思い出しても冷や汗をかいてしまいますよね。
-
【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
【お題】 ・買ったばかりの自転車を分解してひと言
-
あなたの習慣について教えてください!!
あなたが習慣だと思って実践しているものを共有してくださいませんか? 筋肉トレーニングでも朝シャワーでも、あなたが習慣だなと思えば何でも構いません
-
配列を使わずに、変数名を動的にループで回したい
C言語・C++・C#
-
関数から配列を返すには?
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Application.ScreenUpdating = ...
-
ACCESS テキストボックスを隙...
-
phpでボタンを押したときに変数...
-
講義でわからないのですが以下...
-
コンボボックスのtag情報の取得...
-
[python] 文字列を変数名として...
-
ASPへの値渡し
-
構造体の変数の値を、動的に取...
-
「*:*」って何を意味するのでし...
-
UWSC:ポップアップウインドウ...
-
JSONで文字列が長い時
-
formで特定のinputを送信しない...
-
VB6で、長い時間かかる処理...
-
実行中の変数の中身をイミディ...
-
16進の10進変換について
-
malformed header from script....
-
C言語のflagの使い方が分かりま...
-
文字の横にプルダウンを表示さ...
-
セレクトメニューで2つの項目...
-
複数のIP取得
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Application.ScreenUpdating = ...
-
実行時エラー 3020の対策
-
VBAでPDFのコピーとリネームを...
-
ACCESS テキストボックスを隙...
-
[python] 文字列を変数名として...
-
構造体の各データの表示につい...
-
FindFirst を複数条件で検索
-
「*:*」って何を意味するのでし...
-
構造体の変数の値を、動的に取...
-
コンボボックスのtag情報の取得...
-
vbaでxmlからNodeListでデータ...
-
phpでボタンを押したときに変数...
-
VBA他のブックから値のみ貼付す...
-
C++ コマンドプロンプトでの入...
-
MSXMLでの属性の存在確認法
-
UWSC:ポップアップウインドウ...
-
エクセルVBA シート名の部分一...
-
【メモリ不足で落ちる(python)】
-
2つのpythonがあって、一方で...
-
VBAで特殊文字を出力したい
おすすめ情報