2010-07-20 10 views
10

इस कार्यक्रम पर विचार करें:मैं स्ट्रिंग को कैसे प्रिंट करूं जो __FILE__ सही तरीके से फैलता है?

#include <stdio.h> 
int main() { 
    printf("%s\n", __FILE__); 
    return 0; 
} 

फ़ाइल का नाम के आधार पर, इस कार्यक्रम काम करता है - या नहीं। जिस मुद्दे का सामना कर रहा हूं वह यह है कि मैं वर्तमान फ़ाइल के नाम को एन्कोडिंग-सुरक्षित तरीके से प्रिंट करना चाहता हूं। मैं इस से निपटने के कैसे करूँ

?????????.c(3) : warning C4566: character represented by universal-character-name '\u043F' cannot be represented in the current code page (1252) 

: हालांकि, मामले में फ़ाइल अजीब वर्ण जो वर्तमान कोड पेज में नहीं दर्शाया जा सकता, संकलक एक चेतावनी पैदावार (हक तो) है? मैं __FILE__ द्वारा दिए गए स्ट्रिंग को संग्रहीत करना चाहता हूं उदा। यूटीएफ -16 ताकि मैं रनटाइम पर किसी भी अन्य सिस्टम पर इसे सही ढंग से प्रिंट कर सकूं (संग्रहीत यूटीएफ -16 प्रतिनिधित्व को जो भी रनटाइम सिस्टम उपयोग करता है) में परिवर्तित करके। ऐसा करने के लिए, मुझे यह जानने की ज़रूरत है:

  1. __FILE__ द्वारा दी गई स्ट्रिंग के लिए क्या एन्कोडिंग का उपयोग किया जाता है? ऐसा लगता है कि, कम से कम विंडोज़ पर, वर्तमान सिस्टम कोड पेज (मेरे मामले में, विंडोज -1252) का उपयोग किया जाता है - लेकिन यह अनुमान लगा रहा है। क्या ये सच है?
  2. मैं बिल्ड समय पर अपने स्रोत कोड में उस स्ट्रिंग के यूटीएफ -8 (या यूटीएफ -16) का प्रतिनिधित्व कैसे कर सकता हूं?

मेरा वास्तविक जीवन उपयोग केस: मेरे पास एक मैक्रो है जो वर्तमान प्रोग्राम निष्पादन का पता लगाता है, वर्तमान स्रोत कोड/लाइन नंबर जानकारी को फ़ाइल में लिखता है। यह इस तरह दिखता है:

struct LogFile { 
    // Write message to file. The file should contain the UTF-8 encoded data! 
    void writeMessage(const std::string &msg); 
}; 

// Global function which returns a pointer to the 'active' log file. 
LogFile *activeLogFile(); 

#define TRACE_BEACON activeLogFile()->write(__FILE__); 

इस मामले में टूट जाता है वर्तमान स्रोत फ़ाइल एक नाम जो वर्ण जो वर्तमान कोड, पृष्ठ द्वारा प्रदर्शित नहीं किए जा सकते है।

+0

कौन सा संकलक? – Roddy

+0

@ रोडी: मैं एमएसवीसी 9 का उपयोग कर रहा हूं, लेकिन मुझे g ++ 4.x –

+0

के समाधान में भी रूचि है। यह एमएसवीसी 2015 में पूरी तरह से फंस गया है। माइक्रोसॉफ्ट सिर्फ एक कंपाइलर क्यों नहीं बना सकता है जो खराब नहीं होता है? – Owl

उत्तर

11

उपयोग टोकन चिपकाने ऑपरेटर, इस तरह उपयोग कर सकते हैं। यह कहीं परियोजना प्रॉपर्टीज में है। इसके अलावा, आपको केवल wcout/cout का उपयोग printf/wprintf नहीं करना चाहिए। यूनिकोड अस्तित्व से पहले विंडोज़ को यूनिकोड की आवश्यकता थी, इसलिए उनके पास कस्टम मल्टी-बाइट वर्ण एन्कोडिंग था, जो डिफ़ॉल्ट है। हालांकि, विंडोज यूटीएफ 16 का समर्थन करता है- उदाहरण के लिए, सी #।

#include <iostream> 

int main() { 
    std::wcout << __WFILE__; 
} 
+0

यह बहुत दिलचस्प लग रहा है! हालांकि, यह एक फॉलो-अप प्रश्न ट्रिगर करता है: विस्तृत-वर्ण स्ट्रिंग का क्या एन्कोडिंग उपयोग करता है? UTF-16? या यह एक सादा, unencoded, यूसीएस -2 स्ट्रिंग है? अभी मुझे ऐसा लगता है कि यह केवल 'देरी' मुद्दा है। हालांकि, यह मेरे वर्तमान कोड से बहुत बेहतर है इसलिए मेरे द्वारा +1। –

+0

दुर्भाग्यवश, यह अपेक्षा के अनुसार काम नहीं कर रहा है: यह सिर्फ '???????' प्रिंट करता है अगर फ़ाइल में रूसी नाम है। फ़ाइल को 'डीआईआर' के साथ सूचीबद्ध करते समय यह वही है। शायद '__FILE__' वास्तव में फाइल सिस्टम एन्कोडिंग से जुड़ा हुआ है, लेकिन यह रूसी अक्षरों को दिखाने के लिए विंडोज एक्सप्लोरर का उपयोग करने वाले किसी भी क्षेत्र का सम्मान नहीं करता है? –

+0

मेरी मशीन पर काम करता है। क्या आप कंसोल मोड प्रोग्राम का उपयोग कर रहे हैं? क्या आपने कंसोल को एक साइरिलिक कोड पेज पर स्विच किया है जो ग्लिफ का समर्थन करने वाले फ़ॉन्ट के साथ है? SetConsoleCP (1251) उदाहरण के लिए, कंसोलस फ़ॉन्ट कहें। डिफ़ॉल्ट कंसोल एन्कोडिंग OEM है, इसमें ग्लिफ नहीं हैं। –

-1

एन्कोडिंग के लिए, मुझे अनुमान लगाया जा रहा है कि इसका उपयोग फाइल सिस्टम, शायद यूनिकोड द्वारा किया जाता है।

, यह से निपटने के लिए के रूप में कैसे 'आप इसे की तरह कुछ कोड बदल रहा है मुक्केबाज़ी:

#define TRACE_BEACON activeLogFile()->write(FixThisString(__FILE__)); 

std::string FixThisString(wchar_t* bad_string) { .....} 

(। FixThisString का कार्यान्वयन के छात्र के लिए एक व्यायाम के रूप में छोड़ दिया जाता है)

+0

'__FILE__' एक 'char' स्ट्रिंग है जो' wchar_t' स्ट्रिंग नहीं है। यदि आप ऐसा करना चाहते हैं तो आपको 'एल' को उपसर्ग करने के लिए प्रीप्रोसेसर का उपयोग करना होगा। और फिर आप प्रिंट करने के लिए सही 'printf'-family फ़ंक्शन का उपयोग कर सकते हैं। –

+0

@R: वह जो त्रुटि प्राप्त कर रही है वह यह है कि वह जिस स्ट्रिंग में प्रिंट कर रहा है वह एक '' u u4343 'है जिसमें 16-बिट, यूनिकोड wchar_t होगा। –

-1

सबसे अच्छा समाधान करने के लिए है पोर्टेबल फ़ाइल नाम चरित्र सेट [A-Za-z0-9._-] में स्रोत फ़ाइल नामों का उपयोग करें। चूंकि विंडोज यूटीएफ -8 का समर्थन नहीं करता है, इसलिए आपके कॉन्फ़िगर किए गए स्थानीय भाषा पर निर्भरता के बिना सामान्य तारों में मनमानी गैर-ASCII वर्णों का प्रतिनिधित्व करने का कोई तरीका नहीं है।

जीसीसी शायद परवाह नहीं करता है; यह सभी फ़ाइल नामों को 8 बिट स्ट्रिंग के रूप में मानता है और इसलिए यदि फ़ाइल नाम जीसीसी के लिए सुलभ है, तो इसका नाम प्रतिनिधित्व योग्य होगा। (मुझे पता है कि सिग्विन डिफ़ॉल्ट रूप से एक यूटीएफ -8 वातावरण प्रदान करता है, और आधुनिक * निक्स सामान्य रूप से यूटीएफ -8 होगा।) एमएसवीसी के लिए, आप के विस्तार के लिए L को प्रीपेसर करने के लिए प्रीप्रोसेसर का उपयोग करने में सक्षम हो सकते हैं और प्रारूपित करने के लिए %ls का उपयोग कर सकते हैं। ,

#define WIDEN2(x) L ## x 
#define WIDEN(x) WIDEN2(x) 
#define WFILE WIDEN(__FILE__) 

int main() { 
    wprintf("%s\n", WFILE); 
    return 0; 
} 
+0

-1 की व्याख्या करने के लिए देखभाल? –

-1

MSVC में आप यूनिकोड पर बारी और UTF-16 एन्कोडेड तार प्राप्त कर सकते हैं:

1

__FILE__ हमेशा चरित्र स्ट्रिंग शाब्दिक करने का विस्तार होगा, इस प्रकार संक्षेप में यह char const* के लिए संगत हो जाएगा। इसका मतलब यह है कि एक संकलक कार्यान्वयन में कच्चे स्रोत फ़ाइल नाम के बाइट प्रतिनिधित्व का उपयोग करने से अधिक विकल्प नहीं है क्योंकि यह स्वयं संकलन समय पर प्रस्तुत करता है।

किया जाए या नहीं इस वर्तमान स्थान में कुछ समझदार है या नहीं कोई फर्क नहीं पड़ता, आप अपने रन टाइम प्रणाली और संकलक एक वैध फ़ाइल नाम के रूप में स्वीकार के रूप में, एक स्रोत फ़ाइल का नाम है कि मूल रूप से कचरा शामिल हो सकता था जब तक ।

यदि आप, उपयोगकर्ता के रूप में, आपके फ़ाइल सिस्टम में उपयोग किए जाने से अलग एन्कोडिंग के साथ एक अलग लोकेल है, तो आप बहुत सारे देखेंगे ???? या एक जैसे।

लेकिन अगर दोनों अपने स्थानों एन्कोडिंग पर सहमत, एक सादे printf पर्याप्त होना चाहिए और अपने टर्मिनल (या जो भी आप उत्पादन को देखने के लिए उपयोग करें) सही ढंग से पात्रों मुद्रित करने के लिए सक्षम होना चाहिए।

तो संक्षिप्त उत्तर यह है कि यह केवल तभी काम करेगा यदि आपका सिस्टम लगातार w.r.t एन्कोडिंग है। अन्यथा आपकी किस्मत से बाहर, अनुमान लगाते हुए एन्कोडिंग एक कठिन काम है।

संबंधित मुद्दे

 संबंधित मुद्दे