2012-11-21 11 views
5

olarak satır numarası, ancak __FILE__ makro "lib/example/example.cpp" genişleyecek ve __LINE__ bir tamsayı olarak 34 genişler. Önişlemci ile istenilen dizeyi yapabilir miyim? KİK kapsamları tamam.CPP önişlemci ve dosya adının basename, ben önişlemcisinden ile forma <code>"example.cpp:34"</code> statik dize üretmek isterseniz dize

Düzenleme Burada en önemli kısım, statik bir C stili dizgisi olmasını sağlamaktır, dolayısıyla basename işlevini kullanamıyorum. Önişlemcideki bu işlevselliği çoğaltmanın bir yolu var mı?

+0

mi C++ 11 tamam mı? Önişlemcide veya derleme zamanında kullanılabilen dizgiyi mi olmalı? – kennytm

+0

@KennyTM Hayır, C++ 11 kullanamıyorum. Derleme zamanında istiyorum. Boost da iyidir. –

+0

Ya da '__FILE__' kullanmayın, ancak her bir ilgili dosyanın üstüne kendi dizginizi hazırlayın. – chill

cevap

0

Sen __FILE__ genişledikçe sadece const C dize

__FILE__ Bu makro sabiti C dizesi biçimindeki, geçerli giriş dosyasının adı genişler için basename() kullanmak mümkün olmalıdır .

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

Statik bir c-string istiyorum, bu yüzden bir fonksiyonun çıkışı olamaz. –

+0

@pythonicmetaphor Bir fonksiyonun çıkışı nedir? onu bir işlevden mi geri almak istiyorsunuz? – iabdalkader

+0

Demek istediğim statik bir dize istiyorum, bu yüzden herhangi bir işlevi kullanamıyorum, sadece bunu yapmak için ön işlemciyi kullanıyorum. –

2

Sen bitişik dize hazır birleştirilmiş olmasından yararlanabilirsiniz:

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

Sonra FILELINE(__LINE__) gibi kullanırız. Bunu çok sık yapmıyorum, dolayısıyla __LINE__ makrosunu geçmek zorunda kalmanın daha iyi bir yolu olabilir. O ile test, zaten benim için çalışıyor:

#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; 
} 

alıyorum:

main.cpp:9 
+0

Elbette, bu yüzden sorun gerçekten basename. Main.cpp olsun, çünkü farklı bir dizinde dosya eklemediniz. –

0
Ben basename almanın bir yolu bilmiyorum

ancak stringification önişlemci operatörü kullanılır ki daha Oyther gibi '#',:

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

"lib/example/example.cpp:34" genişleyecek (eğer ofc, o hat üzerinde o dosyaya koydu verilen :))

0

Eh, sadece önişlemci kullanılmalıdır - ama son kullanıcıya görünmeyecektir.

Eğer BASENAME() istediğiniz

bazı dosyada kullanılacak - Bu başlık dosyasını basename.h kullanın:

// 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__)) 

bir ideone example here.

basename_start(__FILE__)

verilen kaynak dosyası için yalnızca bir kez değerlendirilecektir. Maalesef bu çözümü başlık dosyalarında kullanamazsınız - sadece kaynak dosyalarında. Bunu değiştirebilirsiniz, bu yüzden her yerde kullanılabilir - ancak verilen dosya adı için taban çizgisinin başlangıcı her seferinde hesaplanacaktır. Sadece bu otomatik olabilir en iyisi inanıyoruz BASENAME() basename_start_calc(__FILE__) yerine basename_start(__FILE__) ...

kullanmak.Her dosya makroda elle tanımlayabilirsiniz Tabii

:

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

ama istediğinin bu olduğundan emin değilim ....