

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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- 英語 what間接疑問.関係代名詞判別法! 2 2023/08/18 20:03
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- PHP PHPでユーザー情報を入力して簡易ログイン機能をつくってみたのですが 1 2023/05/29 08:51
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- JavaScript GoogleChart 階層ごとのブロックの長さを個別に設定したい 1 2022/07/06 14:27
- JavaScript javascript作成してます。ラジオボタンで判定するコードを書いてます。 1 2023/07/18 11:03
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
今、見られている記事はコレ!
-
弁護士が語る「合法と違法を分けるオンラインカジノのシンプルな線引き」
「お金を賭けたら違法です」ーーこう答えたのは富士見坂法律事務所の井上義之弁護士。オンラインカジノが違法となるかどうかの基準は、このように非常にシンプルである。しかし2025年にはいって、違法賭博事件が相次...
-
釣りと密漁の違いは?知らなかったでは済まされない?事前にできることは?
知らなかったでは済まされないのが法律の世界であるが、全てを知ってから何かをするには少々手間がかかるし、最悪始めることすらできずに終わってしまうこともあり得る。教えてgooでも「釣りと密漁の境目はどこです...
-
カスハラとクレームの違いは?カスハラの法的責任は?企業がとるべき対応は?
東京都が、客からの迷惑行為などを称した「カスタマーハラスメント」、いわゆる「カスハラ」の防止を目的とした条例を、全国で初めて成立させた。条例に罰則はなく、2025年4月1日から施行される。 この動きは自治体...
-
なぜ批判コメントをするの?その心理と向き合い方をカウンセラーにきいた!
今や生活に必要不可欠となったインターネット。手軽に情報を得られるだけでなく、ネットを介したコミュニケーションも一般的となった。それと同時に顕在化しているのが、他者に対する辛らつな意見だ。ネットニュース...
-
大麻の使用罪がなかった理由や法改正での変更点、他国との違いを弁護士が解説
ドイツで2024年4月に大麻が合法化され、その2ヶ月後にサッカーEURO2024が行われた。その際、ドイツ警察は大会運営における治安維持の一つの方針として「アルコールを飲んでいるグループと、大麻を吸っているグループ...
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Application.ScreenUpdating = ...
-
[python] 文字列を変数名として...
-
コンボボックスのtag情報の取得...
-
FindFirst を複数条件で検索
-
パイソンプログラミング
-
Pythonでリストの要素の順番を...
-
【至急!!!】python言語で本を見...
-
print <<"_HTML_"の中でサブル...
-
SELECT OPTIONの中身をコピペ...
-
子windowsからsubmit()後にclos...
-
pythonでのリスト内抽出について
-
<python> 文字列か数字かの判別
-
Perlで自分自身の関数名を知る...
-
シェルスクリプトで、空白(ス...
-
pythonの*
-
文字のカラーとフォントの指定...
-
Perl SendMail Bcc メルマガ
-
formで特定のinputを送信しない...
-
Pythonのプログラミングの質問...
-
条件文の扱い方について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Application.ScreenUpdating = ...
-
実行時エラー 3020の対策
-
FindFirst を複数条件で検索
-
ACCESS テキストボックスを隙...
-
[python] 文字列を変数名として...
-
vbaでxmlからNodeListでデータ...
-
VBAでPDFのコピーとリネームを...
-
コンボボックスのtag情報の取得...
-
【メモリ不足で落ちる(python)】
-
構造体の各データの表示につい...
-
構造体の変数の値を、動的に取...
-
phpでボタンを押したときに変数...
-
VBAで特殊文字を出力したい
-
C言語でテキストを抽出
-
PHP+SQLiteでmax(id)が使えない?
-
「*:*」って何を意味するのでし...
-
C++ コマンドプロンプトでの入...
-
2つのpythonがあって、一方で...
-
VBAでシート名の定義を変更した...
-
GUI操作のCUI化
おすすめ情報