2009-05-17 19 views
42

मैं इसे सी # और डेल्फी में कर रहा हूं, लेकिन सी ++ बुरा है। उद्देश्य वर्तमान निर्देशिका में फ़ाइल बनाना है (जहां निष्पादन योग्य चल रहा है)।वर्तमान निर्देशिका कैसे प्राप्त करें?

मेरे कोड:

LPTSTR NPath = NULL; 
DWORD a = GetCurrentDirectory(MAX_PATH,NPath); 
HANDLE hNewFile = CreateFile(NPath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); 

मैं GetCurrentDirectory पर अपवाद()।

कृपया मुझे बताओ कि क्यों मैं एक अपवाद हो और मैं इसे कैसे सी ++ में आसान कर सकता हूँ?

+2

# शामिल चार * getcwd (चार * buf, size_t आकार); http://stackoverflow.com/questions/298510/how-to-get-the-current-directory-in-ac-program की – Anuswadh

+0

संभव डुप्लिकेट [मैं निर्देशिका है कि एक कार्यक्रम है कैसे मिलता है से चल रहा है?] (http://stackoverflow.com/questions/143174/how-do-i-get-the-directory-that-a-program-is-running-from) – user

+2

कृपया ध्यान दें: वर्तमान निर्देशिका हमेशा नहीं है निर्देशिका जो exe में है। (उदाहरण के लिए c: \ users \ me> \ dir1 \ dir2 \ runme.exe यहां आप c: \ users \ me में हैं और \ dir1 \ dir2 \ ex से exe चला रहे हैं।)। – Mercury

उत्तर

97

मैं, सी पर एक किताब पढ़ सिफारिश करेंगे ++ इससे पहले कि आप किसी भी आगे जाना है क्योंकि यह एक मजबूत आधार पाने के लिए उपयोगी होगा। Koenig और Moo द्वारा Accelerated C++ उत्कृष्ट है।

प्राप्त करने के लिए निष्पादन योग्य पथ का उपयोग GetModuleFileName:

char buffer[MAX_PATH]; 
GetModuleFileName(NULL, buffer, MAX_PATH); 

यहाँ एक सी ++ समारोह है कि फ़ाइल नाम के बिना निर्देशिका हो जाता है:

#include <windows.h> 
#include <string> 
#include <iostream> 
using namespace std;; 

string ExePath() { 
    char buffer[MAX_PATH]; 
    GetModuleFileName(NULL, buffer, MAX_PATH); 
    string::size_type pos = string(buffer).find_last_of("\\/"); 
    return string(buffer).substr(0, pos); 
} 

int main() { 
    cout << "my directory is " << ExePath() << "\n"; 
} 
+4

एनबी कि आपको विस्तृत char का उपयोग करने की आवश्यकता हो सकती है, जैसे wchar_t buffer [MAX_PATH]; इन दिनों ... – rogerdpack

+2

या 'GetModuleFileNameA' – Mikhail

+1

@ मिखाइल ने जो कहा है, उसे दोहराने के लिए, आप कोड के लिए' GetModuleFileNameA' का उपयोग करेंगे जो बहु-बाइट वर्ण सेट का उपयोग करता है, और यूनिकोड के लिए 'GetModuleFileNameW' का उपयोग करता है। 'GetModuleFileName' ('ए' या' डब्ल्यू' के बिना) वास्तव में आपके प्रोजेक्ट को सेट करने के लिए सेट किए गए किसी भी चरित्र के लिए एक उपनाम है, जो स्ट्रिंग का उपयोग करने वाले अधिकांश Win32 API विधियों को सेट अप किया जाता है। तो यदि आपके पास एक यूनिकोड प्रोजेक्ट है, और आपके तार भी यूनिकोड हैं, तो आपको केवल 'GetModuleFileName' को कॉल करना होगा। वही लागू होता है यदि आपकी परियोजना बहु-बाइट है और बहु-बाइट तारों का उपयोग करती है। – RectangleEquals

30

GetCurrentDirectory परिणाम के लिए जगह आवंटित नहीं है, यह है कि ऐसा करने के लिए आप पर निर्भर है।

TCHAR NPath[MAX_PATH]; 
GetCurrentDirectory(MAX_PATH, NPath); 

इसके अलावा, Boost.Filesystem पुस्तकालय पर एक नज़र डालें, तो आप इस सी ++ तरीके से करना चाहते हैं।

+0

हम्म, एनपीएथ एक और निर्देशिका को इंगित करता है, मैं इसे निर्देशिका कैसे दिखा सकता हूं जहां निष्पादन योग्य रखा गया है? –

+6

वर्तमान निर्देशिका निष्पादन योग्य की निर्देशिका के समान नहीं है, यहां तक ​​कि सी # और डेल्फी के तहत भी। शायद आप अपना प्रश्न स्पष्ट कर सकते हैं? –

+0

जॉन, यह थोड़ा और अधिक शामिल है और किसी टिप्पणी में इसका उत्तर नहीं दिया जा सकता है। शायद आपको नील की सलाह (दोनों) का पालन करना चाहिए। – avakar

4

आपको एक मान्य बफर प्लेसहोल्डर प्रदान करना चाहिए। है जो:

TCHAR s[100]; 
DWORD a = GetCurrentDirectory(100, s); 
2

GetCurrentDirectory() वर्तमान निर्देशिका है जो जहां exe से शुरू हो जाती है हो जाता है। Exe का स्थान प्राप्त करने के लिए, GetModuleFileName (NULL ...) का उपयोग करें। यदि आपके पास exe के लिए हैंडल है, या आप इसे GetCommandLine() से प्राप्त कर सकते हैं यदि आप नहीं करते हैं।

श्री बटरवर्थ बताते हैं के रूप में, आप एक संभाल की जरूरत नहीं है।

+3

असल में, आपको वास्तविक हैंडल की आवश्यकता नहीं है - एक नल हैंडल को पथ के साथ निष्पादन योग्य फ़ाइल नाम मिलता है। –

-1

निर्देशिका को खोजने के लिए जहां अपने निष्पादन योग्य है, तो आप उपयोग कर सकते हैं:

TCHAR szFilePath[_MAX_PATH]; 
::GetModuleFileName(NULL, szFilePath, _MAX_PATH); 
3

कृपया मत भूलना उन्हें का उपयोग करने से पहले कुछ करने के लिए अपने बफ़र्स प्रारंभ करने में। और बस के रूप में महत्वपूर्ण, न खत्म होने वाली अशक्त

TCHAR path[MAX_PATH+1] = L""; 
DWORD len = GetCurrentDirectory(MAX_PATH, path); 

Reference

9

यहाँ IMHO के लिए अपने स्ट्रिंग बफ़र्स स्थान देने anon's answer में कुछ सुधार कर रहे हैं।

#include <windows.h> 
#include <string> 
#include <iostream> 

std::string GetExeFileName() 
{ 
    char buffer[MAX_PATH]; 
    GetModuleFileName(NULL, buffer, MAX_PATH); 
    return std::string(buffer); 
} 

std::string GetExePath() 
{ 
    std::string f = GetExeFileName(); 
    return f.substr(0, f.find_last_of("\\/")); 
} 
+0

यह वास्तव में अलग है। आप निर्देशिका पथ प्रदान नहीं करते हैं, आप फ़ाइल सहित फ़ाइल का पथ प्रदान करते हैं। – dyesdyes

1
WCHAR path[MAX_PATH] = {0}; 
GetModuleFileName(NULL, path, MAX_PATH); 
PathRemoveFileSpec(path); 
1
#include <windows.h> 
using namespace std; 

// The directory path returned by native GetCurrentDirectory() no end backslash 
string getCurrentDirectoryOnWindows() 
{ 
    const unsigned long maxDir = 260; 
    char currentDir[maxDir]; 
    GetCurrentDirectory(maxDir, currentDir); 
    return string(currentDir); 
} 
3

आप और अधिक सुरुचिपूर्ण तरीके के साथ GetModuleFileName() से फ़ाइल नाम निकाल सकते हैं:

TCHAR fullPath[MAX_PATH]; 
TCHAR driveLetter[3]; 
TCHAR directory[MAX_PATH]; 
TCHAR FinalPath[MAX_PATH]; 
GetModuleFileName(NULL, fullPath, MAX_PATH); 
_splitpath(fullPath, driveLetter, directory, NULL, NULL); 
sprintf(FinalPath, "%s%s",driveLetter, directory); 

आशा है कि यह मदद करता है!यूनिकोड विकास के वातावरण के साथ मेरी सीएई परियोजना से

-3
String^ exePath = Application::ExecutablePath;<br> 
MessageBox::Show(exePath); 
0

कोड के टुकड़े:

/// @brief Gets current module file path. 
std::string getModuleFilePath() { 
    TCHAR buffer[MAX_PATH]; 
    GetModuleFileName(NULL, buffer, MAX_PATH); 
    CT2CA pszPath(buffer); 
    std::string path(pszPath); 
    std::string::size_type pos = path.find_last_of("\\/"); 
    return path.substr(0, pos); 
} 

बस templete CA2CAEX या CA2AEX जो आंतरिक एपीआई कॉल का उपयोग :: MultiByteToWideChar या :: WideCharToMultiByte

2
#include <iostream>  
#include <stdio.h> 
#include <dirent.h> 

std::string current_working_directory() 
{ 
    char* cwd = _getcwd(0, 0) ; // **** microsoft specific **** 
    std::string working_directory(cwd) ; 
    std::free(cwd) ; 
    return working_directory ; 
} 

int main(){ 
    std::cout << "i am now in " << current_working_directory() << endl; 
} 

मैं GetModuleFileName का सही उपयोग करने में विफल रहा। मैंने यह काम बहुत अच्छा पाया। अभी विंडोज़ पर परीक्षण किया गया है, अभी तक लिनक्स पर प्रयास नहीं किया गया है :)

1

कोई भी इस सरल कोड का उपयोग क्यों नहीं करता?

TCHAR szDir[MAX_PATH] = { 0 }; 

GetModuleFileName(NULL, szDir, MAX_PATH); 
szDir[std::string(szDir).find_last_of("\\/")] = 0; 

या और भी आसान

TCHAR szDir[MAX_PATH] = { 0 }; 
TCHAR* szEnd = nullptr; 
GetModuleFileName(NULL, szDir, MAX_PATH); 
szEnd = _tcsrchr(szDir, '\\'); 
*szEnd = 0; 
संबंधित मुद्दे