構造体メンバーのカンマ区切り出力をしたいと思っています。
たとえば
struct XXX {
char name[20];
char address[40];
char tel[12];
... 100メンバーくらいある
}
のような構造体があったとします。
printf("%s,%s,%s\n", s_ptr->name, s_ptr->address, s_ptr->tel);
などのようにメンバー名(変数名)を参照せずに、構造体のメンバーへのポインタを順次取得しループして出力するなどして、実現することは可能でしょうか?
No.2ベストアンサー
- 回答日時:
こんにちわ。
構造体のメンバー名を使用せずにポインタでアクセスする事は可能ですが、
移植性やメンテナンス効率が悪くなるので、通常はあまりやりません。
例えば例にある構造体で、
st *struct XXX;
となっていた場合、
strcpy(tel, ((char *)(st) + 60));
とすれば、tel メンバーにアクセスできます。
※ 構造体内に様々なデータ型を含む場合は、領域が獲得される領域が
整列されるため、構造体内のオフセットの計算に注意する必要が
あります。
以前使っていたマクロですが、
#defineSTOFFSET(st ,member)((long)(&((st *)0)->member))
と宣言して、
printf("Offset (tel) = %d\n", STOFFSET(struct XXX, tel));
とすれば、メンバー内のオフセットを計算できます。
参考にして下さいね。
ご回答詳細にありがとうございます。
いただいた情報を元にさらに調べたところ、taka_tetsu様のご回答の“からくり”の部分に相当することなのですね。
いただいた情報から更に検索すると下記の情報も得られました。
どうもありがとうございました。
--<C FAQ>--
2.14:
構造体内のフィールドのバイトオフセットを知る方法は。
A:
ANSI Cは、offsetofマクロを用意しているので、用意されている場合 は使うこと。<stddef.h>を参照。もし手に入れることができなければ、 実装の一つは以下のようになる。
#define offsetof(type, mem) ((size_t) \
((char *)&((type *)0)->mem - (char *)(type *)0))
この実装も100%の移植性を持つわけではない。コンパイラの中には、 はねつけるものがあるかもしれないが、それはそれで文法的に正しい。
次の質問2.15への解答を、使い方の参考にすること。
References:
ANSI Sec. 4.1.5; ISO Sec. 7.1.6; Rationale Sec. 3.5.4.2; H&S Sec. 11.1 pp. 292-3.
--------------------------------------------------------------------------------
2.15:
どうやれば構造体のフィールドを、実行時に名前でアクセスできるか。
A:
まずoffsetof()マクロを使って名前とオフセットの対応表を用意する。 構造体aのフィールドbのオフセットは、
offsetb = offsetof(struct a, b)
で与えられる。もし以下の式でstructpが、構造体の実体へのポイン ターで、bが上で計算したオフセットを持つintのフィールドとすると、 bの値は間接的に
*(int *)((char *)structp + offsetb) = value;
として得られる。
--
No.6
- 回答日時:
構造体のメンバーをポインタにできるのなら比較的楽ですね。
以下のように union にしてもよいですし、無理矢理 cast しちゃってもよいですし。
union uXXX {
struct XXX {
char *name;
char *address;
char *tel;
:
}
char* aaa[100];
};
どうもありがとうございます!
残念ながら、構造体は私が設計したものではないので、いじれないのです。 (;_;
これ、おもしろいですね!
参考にさせていただきます。ありがとうございます。
No.5
- 回答日時:
なんかそもそもそのような構造体を作ること自体の設計に問題がありそうですけど。
もし、メンバーが全部char ならば(つまり同一という意味)、
struct XXX {
char *member[100];
} s;
enum {_name, _address, _tel, ...} index;
として、
s.member[_name] = "namae";
....
そして、まとめて取り扱うときには、
index = 0;
s.member[index]
のようにするのが普通と思います。
いかがでしょう?
どうもありがとうございます!
残念ながら、構造体は私が設計したものではないので、いじれないのです。
どうもありがとうございます。
教えていただいた方法というのもありですね。
どうもありがとうございます。
No.3
- 回答日時:
いっそのこと構造体を typedef で型にしてからその配列にアクセスするという方法はどうです?
*************************************************
#include <stdio.h>
typedef struct {
int hoge;
int piyo;
char name[64];
} DATA;
int main(void){
int i;
DATA data[] = { { 10, 20, "hoge" },
{ 20, 30, "piyo" },
{ 30, 40, "name" } };
for( i = 0; i < 3; i++ ){
printf( "%d,%d,%s\n", data[i].hoge, data[i].piyo, data[i].name );
}
return 0;
}
*************************************************
これなら動的に確保することも容易ですし。
ご回答ありがとうございます。
恐れ入りますが、構造体のインスタンス?(コピー)が多いのではなく、あくまで「メンバー」が多いので、メンバー名を使用したくないのです。
よろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# プログラムが書けません。 4 2023/01/22 22:57
- C言語・C++・C# スタックフレームの消滅 6 2023/05/20 12:33
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- Visual Basic(VBA) VBAでのMATCH関数 3 2022/10/17 19:06
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- その他(パソコン・周辺機器) チャレンジタッチ3 改造 アプリインストールできない 1 2022/07/01 14:43
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
文字列内の数字削除
-
SetWindowTextについて。
-
構造体が戻り値の関数について...
-
WM_CHAR or WM_KEYDOWN の「wPa...
-
C言語のintとcharの違いってな...
-
C言語にて構造体のメンバがNULL...
-
new charとnew char[N]の違いは?
-
文字列str内の全ての数字を...
-
C言語において、以下の条件で...
-
strcat関数を自作したいです
-
ポインタを使用 [数字列を数値...
-
DWORDとcharの変換
-
文字列の途中から途中までを抽出
-
C言語で文字列をかえす正しい書...
-
文字の代入とコピーについて
-
小数点入りの文字列をfloat型に...
-
callocについて
-
'\\0'とはなんですか?
-
p = (char **)*p の意味
-
C言語を用いた環境変数の作成/...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
char*を初期化したいのですが
-
C言語のintとcharの違いってな...
-
CStringからchar*への型変換に...
-
C言語にて構造体のメンバがNULL...
-
小数点入りの文字列をfloat型に...
-
C言語のプログラムについてです
-
strcat関数を自作したいです
-
fstream型オブジェクトを関数の...
-
new charとnew char[N]の違いは?
-
DWORDとcharの変換
-
文字列の途中から途中までを抽出
-
char 文字列型 の表現範囲が-12...
-
const char* s1とただのchar s1...
-
wsprintf( ポインタ , "%d" , "...
-
c言語でポインタ変数を用いた配...
-
char型にint型の数値を代入する。
-
C言語で文字列をかえす正しい書...
-
C++17で、unsigned char * 配列...
-
共用体について
-
エクセルのMID関数は、C言語では?
おすすめ情報