C 言語で現在のディレクトリを取得する

  1. 関数 getcwd を使って現在の作業ディレクトリを取得する
  2. C 言語で現在の作業ディレクトリを取得するために getcwd 関数から返される値を適切に検証する
  3. 関数 get_current_dir_name を用いて現在の作業ディレクトリを取得する

この記事では、C 言語で現在の作業ディレクトリを取得する方法をいくつか説明します。

関数 getcwd を使って現在の作業ディレクトリを取得する

関数 getcwd は POSIX に準拠したシステムコールであり、呼び出し元のプログラムの現在の作業ディレクトリを取得できます。getcwd は 2つの引数をとり、パス名が格納されたバッファ char* とバッファに確保されたバイト数です。この関数は現在の作業ディレクトリの名前をヌル文字で終端する文字列として格納し、char* のアドレスにパス名を格納するのに十分なスペースがあることを保証するのはユーザの責任です。getcwd はディレクトリの絶対パス名を返すことに注意してください。

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

#ifndef MAX_BUF
#define MAX_BUF 200
#endif

int main(void) {
    char path[MAX_BUF];

    getcwd(path, MAX_BUF);
    printf("Current working directory: %s\n", path);

    exit(EXIT_SUCCESS);
}

C 言語で現在の作業ディレクトリを取得するために getcwd 関数から返される値を適切に検証する

関数 getcwd は正しい値の取得に失敗することがあるので、その場合は NULL を返し、対応するエラーコードとともに errno を設定します。ユーザはエラーチェックコードを実装し、与えられたシナリオに応じて必要に応じてプログラムの制御フローを修正する責任があります。errno を設定することを約束するライブラリ関数を呼び出す前に、getcwd 関数呼び出しの前に明示的に errno をゼロに設定することに注意してください。引数のサイズが作業ディレクトリのパス名よりも小さい場合、errnoERANGE に設定されます。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#ifndef MAX_BUF
#define MAX_BUF 200
#endif

int main(void) {
    char path[MAX_BUF];

    errno = 0;
    if (getcwd(path, MAX_BUF) == NULL) {
        if (errno == ERANGE)
            printf("[ERROR] pathname length exceeds the buffer size\n");
        else
            perror("getcwd");
        exit(EXIT_FAILURE);
    }
    printf("Current working directory: %s\n", path);

    exit(EXIT_SUCCESS);
}

あるいは、getcwd 関数の第 1 引数に NULL を、第 2 引数に 0 を渡すこともできます。この関数自体は malloc を用いて動的に十分な大きさのバッファを確保し、その場所への char ポインタを返します。返されたポインタに対して free 関数を呼び出してバッファメモリを解放しなければならないことに注意してください。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#ifndef MAX_BUF
#define MAX_BUF 200
#endif

int main(void) {
    char path[MAX_BUF];

    errno = 0;
    char *buf = getcwd(NULL, 0);
    if (buf == NULL) {
        perror("getcwd");
        exit(EXIT_FAILURE);
    }
    printf("Current working directory: %s\n", buf);
    free(buf);

    exit(EXIT_SUCCESS);
}

関数 get_current_dir_name を用いて現在の作業ディレクトリを取得する

get_current_dir_name も現在の作業ディレクトリを取得するための別の関数です。この関数は _GNU_SOURCE マクロを定義する必要があるので、コンパイルエラーが発生する可能性があることに注意してください。get_current_dir_name は引数を取らず、getcwd 関数と同様に char ポインタを返します。メモリは malloc を用いて自動的に確保され、返されたポインタを解放するのは呼び出し元のコードの責任です。

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#ifndef MAX_BUF
#define MAX_BUF 200
#endif

int main(void) {
    char path[MAX_BUF];

    errno = 0;
    char *buf = get_current_dir_name();
    if (buf == NULL) {
        perror("get_current_dir_name");
        exit(EXIT_FAILURE);
    }
    printf("Current working directory: %s\n", buf);
    free(buf);

    exit(EXIT_SUCCESS);
}