2010-05-19 9 views
15

मुझे वर्तमान कार्य निर्देशिका प्राप्त करने के लिए एक क्रॉस-प्लेटफार्म तरीका चाहिए (हाँ, getcwd जो मैं चाहता हूं)। मैंने सोचा था कि इस चाल हो सकती:वर्तमान निर्देशिका प्राप्त करने के लिए एक क्रॉस-प्लेटफार्म तरीका क्या है?

#ifdef _WIN32 
    #include <direct.h> 
    #define getcwd _getcwd // stupid MSFT "deprecation" warning 
#elif 
    #include <unistd.h> 
#endif 
#include <string> 
#include <iostream> 
using namespace std; 

int main() 
{ 
    string s_cwd(getcwd(NULL,0)); 
    cout << "CWD is: " << s_cwd << endl; 
} 

मैं इस पढ़ने मिल गया:

कोई मेमोरी लीक होना चाहिए, और यह एक मैक पर भी काम करना चाहिए, सही?

अद्यतन: मुझे डर है कुछ यहाँ अभी भी गलत है (मैं, के रूप में वहाँ getcwd के लिए एक सभ्य लंबाई प्राप्त करने के लिए कोई उचित तरीके से एक निर्धारित लंबाई के साथ एक चार सरणी बनाने से बचने के लिए कोशिश कर रहा हूँ):

char* a_cwd = getcwd(NULL,0); 
string s_cwd(a_cwd); 
free(a_cwd); // or delete a_cwd? 

उत्तर

12

आप एक न्यूल बफर के साथ getcwd पर कॉल नहीं कर सकते हैं। Opengroup के अनुसार:

तो buf एक अशक्त सूचक, getcwd के व्यवहार (है) अनिर्दिष्ट है।

इसके अलावा, getcwd NULL को वापस कर सकता है जो स्ट्रिंग कन्स्ट्रक्टर को तोड़ सकता है।

char buffer[SIZE]; 
char *answer = getcwd(buffer, sizeof(buffer)); 
string s_cwd; 
if (answer) 
{ 
    s_cwd = answer; 
} 
+2

यदि वह "केवल" विंडोज, लिनक्स और मैक्स ओएस एक्स के साथ संगतता में रुचि रखते हैं, तो 'getcwd (NULL)' अच्छी तरह से परिभाषित किया गया है। वे सभी एक ही तरीके से समारोह का विस्तार करते हैं। –

+0

मैंने इसे स्वीकार कर लिया, लेकिन उपरोक्त टिप्पणी इमो सही है। यद्यपि मेरे कोड में स्मृति रिसाव था, इसलिए लिनक्स के लिए – rubenvb

+0

@ रोबकेनेडी को हल करने की आवश्यकता है, यह लक्षित संस्करण पर निर्भर करता है। उदाहरण के लिए, आरएचईएल 5 बॉक्स पर, 'getcwd (NULL)' अभी भी अपरिभाषित होने के रूप में प्रलेखित है। –

25

यदि आपके लिए शामिल करने में कोई समस्या नहीं है, तो सुविधाजनक क्रॉस-प्लेटफ़ॉर्म फाइल सिस्टम ऑपरेशंस के लिए boost filesystem का उपयोग करें।

boost::filesystem::path full_path(boost::filesystem::current_path()); 

यहां एक example है।

संपादित करें: के रूप में टिप्पणी में रॉय डेंटन से कहा, फाइल सिस्टम ISO C++ in C++17 का हिस्सा बन गया है, तो बढ़ावा अब कोई आवश्यकता नहीं है:

std::filesystem::current_path(); 
+0

उल्लेख किया है चाहिए::

आप की तरह कुछ करने के लिए है कि को बदलना होगा, बाहरी निर्भरता को सीमित करने की कोशिश कर रहा है ताकि कोई बूस्ट करें। – rubenvb

+4

आह, ठीक है। मैं इस टिप्पणी को तब छोड़ दूंगा जब अन्य लोग इस प्रश्न पर ठोकरें;) – catchmeifyoutry

+2

सी ++ 14/सी ++ 17 के साथ शुरुआत, आप 'std :: फाइल सिस्टम :: current_path()': http: // en का उपयोग कर सकते हैं। cppreference.com/w/cpp/filesystem/current_path –

2

एक शून्य सूचक के साथ getcwd कॉलिंग कार्यान्वयन परिभाषित किया गया है। यह अक्सर आपके लिए मॉलोक के साथ आवंटन करता है (जिस स्थिति में आपके कोड में स्मृति रिसाव होता है)। हालांकि, यह बिल्कुल काम करने की गारंटी नहीं है। तो आपको अपना खुद का बफर आवंटित करना चाहिए।

char *cwd_buffer = malloc(sizeof(char) * max_path_len); 
char *cwd_result = getcwd(cwd_buffer, max_path_len); 

ओपन ग्रुप में एक उदाहरण है कि _PC_PATH_MAX से अधिकतम पथ लंबाई कैसे प्राप्त करें। आप विंडोज पर MAX_PATH का उपयोग करने पर विचार कर सकते हैं। दोनों प्लेटफॉर्म पर इस नंबर पर चेतावनी के लिए this question देखें।

+0

क्या std :: स्ट्रिंग कन्स्ट्रक्टर malloc'ed स्मृति को मुक्त नहीं करेगा? – rubenvb

+0

@ रूबेनव, नहीं, यह सिर्फ स्ट्रिंग को प्रतिलिपि में प्रारंभ करता है। यह जानने का कोई तरीका नहीं है कि 'char *' में पारित किया गया था। –

+0

डैंग, ठीक है, धन्यवाद – rubenvb

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

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