2009-05-17 35 views
42

Tôi đã làm điều này trong C# và Delphi, nhưng C++ là mục đích xấu. Để tạo một tệp trong thư mục hiện tại (nơi tệp thực thi đang chạy).Làm thế nào để có được danh mục hiện tại?

Mã của tôi:

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

tôi nhận được ngoại lệ tại GetCurrentDirectory().

Vui lòng cho tôi biết lý do tôi nhận được ngoại lệ và làm cách nào để làm cho dễ dàng hơn trong C++?

+2

#include char * getcwd (char * buf, size_t size); http://stackoverflow.com/questions/298510/how-to-get-the-current-directory-in-ac-program – Anuswadh

+0

thể trùng lặp của [Làm thế nào để tôi nhận được thư mục đó một chương trình là chạy từ?] (http://stackoverflow.com/questions/143174/how-do-i-get-the-directory-that-a-program-is-running-from) – user

+2

Xin lưu ý: thư mục hiện tại không phải luôn luôn thư mục mà exe đang ở. (ví dụ: c: \ users \ me> \ dir1 \ dir2 \ runme.exe ở đây bạn đang ở trong c: \ users \ me và chạy exe từ \ dir1 \ dir2 \). – Mercury

Trả lời

97

Tôi khuyên bạn nên đọc một cuốn sách về C++ trước khi bạn tiến xa hơn nữa, vì sẽ hữu ích nếu bạn có được một nền tảng vững chắc hơn. Accelerated C++ bởi Koenig và Moo là tuyệt vời.

Để có được con đường thực thi sử dụng GetModuleFileName:

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

Dưới đây là một hàm C++ mà được thư mục mà không có tên tập tin:

#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

NB mà bạn có thể cần phải sử dụng một char rộng, giống như bộ đệm wchar_t [MAX_PATH]; những ngày này ... – rogerdpack

+2

Hoặc 'GetModuleFileNameA' – Mikhail

+1

Để nhắc lại những gì @Mikhail đã nói, bạn sẽ sử dụng' GetModuleFileNameA' cho mã sử dụng bộ ký tự nhiều byte và 'GetModuleFileNameW' cho unicode. 'GetModuleFileName' (không có' A' hoặc 'W') thực sự là bí danh cho bất kỳ ký tự nào mà dự án của bạn được thiết lập để sử dụng, đó là cách mà hầu hết các phương thức Win32 API sử dụng chuỗi được thiết lập. Vì vậy, nếu bạn có một dự án unicode, và các chuỗi của bạn cũng là unicode, thì bạn sẽ chỉ phải gọi 'GetModuleFileName'. Điều tương tự cũng áp dụng nếu dự án của bạn là đa byte và sử dụng chuỗi nhiều byte. – RectangleEquals

30

GetCurrentDirectory không phân bổ không gian cho kết quả, tùy thuộc vào bạn để thực hiện điều đó.

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

Ngoài ra, hãy xem thư viện Boost.Filesystem nếu bạn muốn thực hiện điều này theo cách C++.

+0

Hmm, NPath trỏ đến một thư mục khác, làm thế nào để làm cho nó hiển thị thư mục nơi thực thi được đặt trong? –

+6

Thư mục hiện tại không giống thư mục thực thi, ngay cả dưới C# và Delphi. Có lẽ bạn có thể làm cho câu hỏi của bạn rõ ràng hơn? –

+0

John, đó là một chút tham gia nhiều hơn và không thể chỉ đơn giản là trả lời trong một bình luận. Có lẽ bạn nên theo lời khuyên của Neil (cả hai). – avakar

4

Bạn nên cung cấp một trình giữ chỗ đệm hợp lệ. đó là:

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

GetCurrentDirectory() được thư mục hiện hành là nơi mà các exe được gọi từ. Để có được vị trí của exe, hãy sử dụng GetModuleFileName (NULL ...). nếu bạn có quyền xử lý exe, hoặc bạn có thể lấy nó từ GetCommandLine() nếu bạn không.

Như ông Butterworth đã chỉ ra, bạn không cần xử lý.

+3

Trên thực tế, bạn không cần một xử lý thực - một xử lý NULL được tên tập tin thực thi, với đường dẫn. –

-1

Để tìm thư mục nơi thực thi của bạn, bạn có thể sử dụng:

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

Xin đừng quên để khởi tạo bộ đệm của bạn để một cái gì đó trước khi sử dụng chúng. Và cũng quan trọng, cung cấp cho không gian bộ đệm chuỗi của bạn cho kết thúc rỗng

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

Reference

9

IMHO đây là một số cải tiến để 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

Điều này thực sự khác. YOu không cung cấp đường dẫn thư mục, bạn cung cấp đường dẫn của tệp, bao gồm tệp. – 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

Bạn có thể loại bỏ các tên tập tin từ GetModuleFileName() với cách thanh lịch hơn:

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); 

Hy vọng nó sẽ giúp!

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

Đoạn mã từ dự án CAE của tôi với môi trường phát triển unicode:

/// @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); 
} 

Chỉ cần sử dụng templete CA2CAEX hoặc CA2AEX trong đó kêu gọi các API nội :: MultiByteToWideChar hoặc :: 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; 
} 

Tôi không thể sử dụng GetModuleFileName một cách chính xác. Tôi thấy công việc này rất tốt. vừa được thử nghiệm trên Windows, chưa thử trên Linux :)

1

Tại sao không ai ở đây xem xét sử dụng mã đơn giản này?

TCHAR szDir[MAX_PATH] = { 0 }; 

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

hoặc thậm chí đơn giản hơn

TCHAR szDir[MAX_PATH] = { 0 }; 
TCHAR* szEnd = nullptr; 
GetModuleFileName(NULL, szDir, MAX_PATH); 
szEnd = _tcsrchr(szDir, '\\'); 
*szEnd = 0; 
Các vấn đề liên quan