Làm thế nào để có được thư mục hiện tại trong một chương trình C?


162

Tôi đang tạo một chương trình C nơi tôi cần lấy thư mục mà chương trình được bắt đầu. Chương trình này được viết cho máy tính UNIX. Tôi đã nhìn opendir()telldir(), nhưng telldir()trả lại một off_t (long int), vì vậy nó thực sự không giúp tôi.

Làm thế nào tôi có thể nhận được đường dẫn hiện tại trong một chuỗi (mảng char)?

Câu trả lời:


291

Bạn đã có một cái nhìn tại getcwd()?

#include <unistd.h>
char *getcwd(char *buf, size_t size);

Ví dụ đơn giản:

#include <unistd.h>
#include <stdio.h>
#include <limits.h>

int main() {
   char cwd[PATH_MAX];
   if (getcwd(cwd, sizeof(cwd)) != NULL) {
       printf("Current working dir: %s\n", cwd);
   } else {
       perror("getcwd() error");
       return 1;
   }
   return 0;
}

11
Chọn lựa chọn tốt nhất, <errno.h> dường như không cần thiết và chương trình báo cáo thành công ngay cả khi thất bại thông qua trạng thái thoát. Nếu không, một ví dụ tốt đẹp.
Jonathan Leffler

21
Ồ, và thông thường hơn là sử dụng printf (...) thay cho fprintf (stdout, ...)?
Jonathan Leffler

19
@JonathanLeffler: Đó không phải là người khó tính nhất. Đây là: int main()nên được int main(void).
Keith Thompson

4
Tôi sẽ sử dụng PATH_MAX từ giới hạn.h, thay vì số ma thuật nếu ~ 4KB trên stack không phải là vấn đề.
jacekmigacz

1
Vẫn không có, bộ đệm của bạn cũng phải phù hợp với byte / null kết thúc chuỗi, do đó, bộ đệm chính xác là char cwd[PATH_MAX+1]. Hoặc nếu bạn không thể bị làm phiền với bộ đệm chỉ char *buf=getcwd(NULL,0);và khi bạn hoàn thành free(buf)(kể từ POSIX.1-2001)
bliako

60

Tra cứu trang người đàn ông cho getcwd.


7
@angad dạy một người đàn ông câu cá nhưng ít nhất chỉ cho anh ta đường đến hồ / biển / đại dương :)
mtk

3
mọi người giới thiệu con người cho những người đang cố gắng sử dụng phương pháp tìm kiếm vượt trội mà google không liên lạc được.
gbtimmon

3
Đoạn mã : man 3 getcwd. Đùa sang một bên, đừng vô chính phủ, bài này là từ '08, các quy ước SO là khác nhau.
Kroltan

2
@gbtimmon google là một công cụ tìm kiếm, nó không giống với trang man. Nó cuối cùng sẽ chỉ đến trang người đàn ông.
Ajay Brahmakshatriya

24

Mặc dù câu hỏi được gắn thẻ Unix, mọi người cũng có thể truy cập nó khi nền tảng mục tiêu của họ là Windows và câu trả lời cho Windows là GetCurrentDirectory()chức năng:

DWORD WINAPI GetCurrentDirectory(
  _In_  DWORD  nBufferLength,
  _Out_ LPTSTR lpBuffer
);

Những câu trả lời này áp dụng cho cả mã C và C ++.

Liên kết được đề xuất bởi user4581602 trong một bình luận cho một câu hỏi khác và được xác minh là lựa chọn hàng đầu hiện tại với trang web tìm kiếm của Google: microsoft.com getciendirectory '.


2
#include <stdio.h>  /* defines FILENAME_MAX */
//#define WINDOWS  /* uncomment this line to use it for windows.*/
#ifdef WINDOWS
#include <direct.h>
#define GetCurrentDir _getcwd
#else
#include <unistd.h>
#define GetCurrentDir getcwd
#endif

int main(){
  char buff[FILENAME_MAX];
  GetCurrentDir( buff, FILENAME_MAX );
  printf("Current working dir: %s\n", buff);
  return 1;
}

3
Tại sao bạn không sử dụng các macro được xác định trước để phát hiện HĐH như #if được xác định (_WIN32) || đã xác định (_WIN64) || đã xác định ( WINDOWS )
HaseeB Mir

1

Lưu ý rằng getcwd(3)cũng có sẵn trong libc của Microsoft: getcwd (3) và hoạt động theo cách bạn mong đợi.

Phải liên kết với -loldnames(oldnames.lib, được thực hiện tự động trong hầu hết các trường hợp) hoặc sử dụng _getcwd(). Phiên bản chưa được chỉnh sửa không có sẵn trong Windows RT.


0

Để có được thư mục hiện tại (nơi bạn thực hiện chương trình mục tiêu của mình), bạn có thể sử dụng mã ví dụ sau, hoạt động cho cả Visual Studio và Linux / MacOS (gcc / clang), cả C và C ++:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined(_MSC_VER)
#include <direct.h>
#define getcwd _getcwd
#elif defined(__GNUC__)
#include <unistd.h>
#endif

int main() {
    char* buffer;

    if( (buffer=getcwd(NULL, 0)) == NULL) {
        perror("failed to get current directory\n");
    } else {
        printf("%s \nLength: %zu\n", buffer, strlen(buffer));
        free(buffer);
    }

    return 0;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.