いつもお世話になっています。
C言語の質問です。
単体テストログを取るために、
“関数Aをコールする前後で、関数Aに引数として渡す構造体のメンバをすべて”printf(もしくはfprintf)で出力して比較確認しなければならないのですが、
構造体のメンバが250とか、150とかあり、メンバ名もxxx_01,xxx_02などのようにエクセルなどで簡単に加工して作れるものではないので、いちいちメンバ名を指定しなければならないのでとても大変です。
オブジェクト指向言語なら、for each文とかでオブジェクトのメンバを簡単に取り出せるのでしょうが(間違っているかもしれません・・・)、C言語で構造体のメンバを、for文などのループを使って簡単に出力できる方法はないでしょうか?
メンバの型は、一定ではなく、char、int、double、別の構造体のポインタ型(これは出力しなくて良い)と混在しています。メンバが全て同一の型ならポインタで構造体の先頭アドレスからsizeof(メンバの型)の分インクリメントしていけば出力できそうな気もしますが、メモリ上に連続して確保されるのかも私にはわからないので困っています。
enumで列挙して・・・というのも調べてみましたが、応用は出来ないようでした。
どなたか、地道にメンバ名を書いて出力する以外の方法をご存知の方、いらっしゃいましたらお知恵をお貸しください。
よろしくお願いいたします。
※説明不足の点がありましたら補足いたします。
No.5ベストアンサー
- 回答日時:
コードを書かないという方向性の提案を一つ。
デバッガに構造体の内容を出力させるというのはどうでしょうか。
struct {
int a;
char *b;
double c;
}
という型を持つ変数xがあったとして、gdbでは下記のような出力が得られます。
(gdb) print x
$1 = {
a = 123,
b = 0x2fd0 "ABC",
c = -9876.5
}
この回答への補足
gdbは、プロジェクト方針で「使用しない」とのことですが、インストールはされていたので使用してみました。思っていたほど難しくなく、デバッグがとても便利になりました。大変役に立つアドバイスありがとうございました。
補足日時:2008/12/19 12:07ご回答ありがとうございます。
家庭内で不慮の悲しい出来事があり御礼が遅れてしまい申し訳ありません。
gdbは導入しておらず(なぜ?)、他にメモリリーク検出のvalgrindなども導入されていないので使用できませんでした。
私自身gdbは名前を知っている程度でしたので、このような使い方が出来るとは知りませんでした。勉強してみたいと思います。
大変参考になる意見ありがとうございました。
No.4
- 回答日時:
#2です。
cvsはcsvの誤りです。
メンバ型はB列にしましたが、最右列にしておけば加工後に列削除や非表示にしなくても選択するときに除くことができます。
やりやすいようにどうぞ。
No.3
- 回答日時:
こんなのはどうでしょう?
#ifdef DUMP
# define STRUCT(name) void dump_##name(const struct name *data, FILE *stream) {
# define END_STRUCT }
# define MEMBER(type, name) print_##type(data->name);
#else
# define STRUCT(name) struct name {
# define END_STRUCT };
# define MEMBER(type, name) type name;
#endif
といったマクロを定義しておいて、
STRUCT(foo)
MEMBER(int, hoge)
MEMBER(double, bar)
...
END_STRUCT
のようにすれば、DUMPマクロの定義状態によって、構造体の定義とダンプ用の関数を生成できるはずです。
ご回答ありがとうございます。
家庭内で不慮の悲しい出来事があり御礼が遅れてしまい申し訳ありません。
マクロは確かに便利そうですね。
マネージャに相談してみたのですが「可読性が低くなる」とのことで却下されてしまいました。。
せっかくお答えいただいたのに申し訳ありません。
今後の参考にさせていただきます。
No.2
- 回答日時:
excelにメンバの型とメンバ名だけをコピーしてから加工→エディタにコピーすればそんなに手間じゃないですよ。
excel側
A列:「printf("」
B列:メンバ型をコピー
C列:メンバ名をコピー
D列:「=if(B1="char *", " %s", if(B1="double", " %lf", " %d"))」
E列:「\n", XXX.」(XXXは構造体変数名)
F列:「=C1」
G列:「);」
A、D~G列をオートフィルでメンバ行数分コピーしたらB列を削除するか非表示にして全選択し、エディタに貼り付けします。
エディタ側では列と列の間がタブで区切られているので、置換機能でタブを削除すればメンバが200でも1000でもあっと言う間に出力文完成。
こんな風。
printf("memb1 %s\n", XXX.memb1);
printf("memb2 %lf\n", XXX.memb2);
…
windowsだったらsakuraエディタのように矩形選択が使えるエディタならメンバ型、名をexcelにコピーするのも楽ですね。
矩形選択が出来ないのならcvsにしてからexcelで読み込むという手間がかかるかな。
ご回答ありがとうございます。
家庭内で不慮の悲しい出来事があり御礼が遅れてしまい申し訳ありません。
エクセルで加工するのが便利ですね。
ただ、行数が多くなってしまうのでうまくいかないものかな・・・(ループ文とかで短いコードで処理)と思い質問させていただきました。
sakuraエディタは出向先の意向により使用できない(同じく矩形選択できるemエディタなども使用できない、使用できるのは秀丸のみ)なので矩形選択ができないのがつらいところです。
No.1
- 回答日時:
そんな便利機能はないので、地道に書くしかありません。
いっそ「構造体の定義を解析してprintf()に変換する」プログラムを書いてしまうのが楽かもしれませんね。
しかしメンバーが100超えって……も少しコンパクトな単位に分けられなかったんでしょうか?
for eachにしても例外はあるかもしれませんが「配列の各要素を先頭から終端まで」なので構造体メンバーの取得には使えません。
ご回答ありがとうございます。
帰宅が遅くなってしまいましたので、とりあえず#1様の欄に返信させていただきます。
#2~#5の方につきましても、後日回答をさせていただきます。
まことに勝手で申し訳ありませんが、ご了承ください。
回答ですが、やはりそのような便利機能はありませんか。
今は、複数ある構造体ごとにそれぞれのメンバを出力する専用関数を作ろうかと考えています。
システムは金融系なのですが、DBのテーブルのカラムをコピーしてExcel2003に貼り付けたら、長すぎて貼り付けられませんでしたので、カラム数だけでExcelの横幅256項目を超えているようです。
構造体もネストの嵐で、ポインタを*、ダブルポインタを**で書くと、
引数として受け取る*構造体Aのメンバに*構造体Bと構造体Cがあり、
*構造体Bのメンバには構造体D配列があり、構造体D各々のメンバに構造体Eがある。
構造体Cのメンバには構造体Fがある。
そして関数には構造体Aの配列として**構造体A配列が渡される・・・
のような(私にはもう何がなにやら・・・の)つくりになっています。
それぞれ、メンバ数は30~250以上とさまざまです。
金融系のシステムって、こんなにデータ使うのか・・・と驚愕している次第です。。
古いシステムのようで、COBOLをC言語でラッパしているようです。
私としては、オブジェクト指向言語で作ればもっと扱いやすくなるのではないか・・・と考えているのですが、なにぶんこの金融危機でお金がないらしくコストのかかる開発はできないようです。
私は元々はVB系(の後にJava経験多少アリ)でしたので、Join関数やSplit関数、LBound関数、UBound関数、Redim関数・・・使い慣れていたものがことごとくC言語に存在しないのでマシン語に近い高級言語とはこういうものかと、良くも悪くもよい経験をさせてもらっています。
私の開発効率が低く、休日出勤になってしまいそうで皆様へのお返事は遅れてしまうかもしれませんが、必ずお返事はいたしますのでしばらくお待ちいただけますようお願いいたします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
準・究極の選択
「年収1000万円で一生カレーライス」か 「年収180万円で毎日何でも食べ放題」 あなたはどちらを選びますか?
-
フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
あなたが普段思っている「これまだ誰も言ってなかったけど共感されるだろうな」というあるあるを教えてください
-
映画のエンドロール観る派?観ない派?
映画が終わった後、すぐに席を立って帰る方もちらほら見かけます。皆さんはエンドロールの最後まで観ていきますか?
-
海外旅行から帰ってきたら、まず何を食べる?
帰国して1番食べたくなるもの、食べたくなるだろうなと思うもの、皆さんはありますか?
-
天使と悪魔選手権
悪魔がこんなささやきをしていたら、天使のあなたはなんと言って止めますか?
-
構造体のメンバをfor文で回したい
C言語・C++・C#
-
C#で、あるクラスのメンバーすべての値を出力したい
C言語・C++・C#
-
関数から配列を返すには?
C言語・C++・C#
-
-
4
構造体配列内の文字列検索のよい方法を教えてください
C言語・C++・C#
-
5
char*を初期化したいのですが
C言語・C++・C#
-
6
C言語にて構造体のメンバがNULLであるかを判定するサンプルを作成して
C言語・C++・C#
-
7
C言語のポインタに直接アドレスを割り振りしたい
C言語・C++・C#
-
8
構造体のポインタにNULLが入らない
C言語・C++・C#
-
9
TCP/IP のパケットの分断と結合について
UNIX・Linux
-
10
文字列ポインタを結合
C言語・C++・C#
-
11
C言語のポインターに関する警告
C言語・C++・C#
-
12
1 つのヘッダファイルに複数のクラスって?
C言語・C++・C#
-
13
PCC-S-02201エラーの対処を教えてください!
Oracle
-
14
C言語での引数の省略方法
C言語・C++・C#
-
15
printf による16進表示について
C言語・C++・C#
-
16
C++言語で、構造体のコピーは可能(しても良い)のでしょうか?
C言語・C++・C#
-
17
C言語初心者の質問失礼します。
C言語・C++・C#
-
18
構文エラー;"が型の前にありませんとは、どうしたら解決できるのですか。"
C言語・C++・C#
-
19
課題でつまってます・・・
C言語・C++・C#
-
20
enumの値から定義名を文字列化したい
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語について。
-
3×3のラテン方陣をつくるプログ...
-
VisualStudio2022でC言語プログ...
-
2つほどお聞きしたいことがあり...
-
UART通信の取説で,left floati...
-
10進数からN進数に変換するプロ...
-
gccを行ってもexeファイルが生...
-
MACで動く実行ファイルをWindow...
-
ストリームについて。
-
Cのコンパイルでコメントアウト...
-
Windows Formアプリからコンソ...
-
パソコン
-
今ってプログラミング言語は何...
-
どうして+3
-
プログラミング言語についてc++...
-
次の記述について
-
C#でTreeViewのCheckBoxのサイ...
-
逆コンパイルと逆アセンブルの...
-
プログラムの実行時に'<'でリダ...
-
私は
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
どうして+3
-
プログラミング言語についてc++...
-
今ってプログラミング言語は何...
-
2つほどお聞きしたいことがあり...
-
次の記述について
-
パソコン
-
バッチファイルで以下のような...
-
大量のデータを読み込んで表示...
-
c言語
-
Windows Formアプリからコンソ...
-
gccを行ってもexeファイルが生...
-
VisualStudio2022でC言語プログ...
-
UART通信の取説で,left floati...
-
C#でTreeViewのCheckBoxのサイ...
-
10進数からN進数に変換するプロ...
-
Python、プログラミングについ...
-
[C言語]fputsとfprintfの違い
-
0 == False はいいけど
-
VisualStudioで、コードを印刷...
-
逆コンパイルと逆アセンブルの...
おすすめ情報