2012-11-21 4 views
5

として行番号が、__FILE__マクロ"lib/example/example.cpp"に拡大すると__LINE__整数として34に展開。プリプロセッサで目的の文字列を構築できますか? GCCエクステンションは正常です。CPPプリプロセッサとファイル名のベース名、Iは、プリプロセッサとフォーム<code>"example.cpp:34"</code>の静的な文字列を生成したい文字列

編集ここで最も重要な部分は、静的なCスタイルの文字列が必要なため、basename関数を使用できません。プリプロセッサにその機能をレプリケートする方法があるのだろうか?あなただけの__FILE__としてbasename()を使用することができるはず

+0

ですC++ 11 OK?プリプロセッサで使用可能な文字列か、コンパイル時に使用できる文字列でなければなりませんか? – kennytm

+0

@KennyTMいいえ、私はC++ 11を使用できません。私はコンパイル時にそれをしたい。ブーストも大丈夫です。 –

+0

または '__FILE__'を使用しないで、それぞれのファイルの上に独自の文字列リテラルを定義してください。 – chill

答えて

0

がconstのC文字列に展開さ

__FILE__ このマクロは、定数C文字列の形式で、現在の入力ファイルの名前に展開。

printf ("%s:%d\n", basename(__FILE__), __LINE__); 
+0

私は静的なC文字列が必要なので、関数の出力にすることはできません。 –

+0

@pythonicmetaphor関数の出力はどういう意味ですか?あなたは関数からそれを戻したいのですか? – iabdalkader

+0

私は静的な文字列が必要なので、関数を使用することはできません。そのためには、プリプロセッサだけを使用します。 –

2

あなたは、隣接する文字列リテラルが連結されているという事実を利用することができますFILELINE(__LINE__)のようにそれを使用すると

#define STRINGIFY(s) #s 
#define FILELINE(line) __FILE__ ":" str(line) 

。私はこれを頻繁にはしないので、__LINE__マクロを渡すよりも良い方法があるかもしれません。それはでテスト、とにかく私の作品:

#include <iostream> 

#define str(s) #s 
#define FILELINE(line) __FILE__ ":" str(line) 

int main(int argc, const char* argv[]) 
{ 
    std::cout << FILELINE(__LINE__) << std::endl; 
    return 0; 
} 

私が手:

main.cpp:9 
+0

確かに、問題は本当にベースネームだと思います。別のディレクトリにファイルを含めていないので、main.cppを取得します。 –

0

私はベース名を取得する方法を知っているが、あなたは文字列化プリプロセッサ演算子を使用することができますよりもoytherはありません以下のような '#'、:今すぐ

#define M__(x,y) x ":" #y 
#define M_(x,y) M__(x, y) 
#define M M_(__FILE__, __LINE__) 

M(:)は、あなたがそのライン上でそのファイルに入れて与えられたOFC)を"lib/example/example.cpp:34"に拡大していきます

0

まあ、プリプロセッサだけでなく、エンドユーザには見えません。

あなたはBASENAME()は、いくつかのファイルで使用することにしたい - このヘッダファイルbasename.h使用:

// basename.h 
#include <string.h> 

static size_t basename_start_calc(const char* filename) 
{ 
    const char* base = strrchr(filename, '/'); 
    return base ? (base - filename + 1) : 0; 
} 
static inline size_t basename_start(const char* filename) 
{ 
    static size_t retval = basename_start_calc(filename); 
    return retval; 
} 
#define STR_(t) #t 
#define STR(t) STR_(t) 
#define BASENAME() ((__FILE__ ":" STR(__LINE__)) + basename_start(__FILE__)) 

ideone example hereを。

basename_start(__FILE__)は、指定されたソースファイルに対して1回だけ評価されます。残念ながら、ヘッダーファイルではこのソリューションを使用することはできません。ソースファイルでのみ使用できます。あなたはそれを変更することができるのでどこでも使用できます - しかし、与えられたファイル名のベースラインの開始は毎回計算されます。 basename_start(__FILE__)の代わりにBASENAME()basename_start_calc(__FILE__)で使用してください...

これは自動的に行うことができます。あなたはすべてのファイルのマクロに手で定義することができます。もちろん

#define BASENAME() ("somefile.cpp:" STR(__LINE__)) 

が、私はこれがあなたが望んでいることを確認していない....

関連する問題