2

我在玩 Cygwin GCC,我想g_get_current_dir在 Windows 和 Linux 中使用 glib 打印当前目录路径。问题是该应用程序在 Windows 中始终以 posix 格式打印路径。但我希望它在 windows 中以 dos 格式打印,在 linux 中以 posix 格式打印。我该怎么做?我知道 cygpath 实用程序,但这是一个外部实用程序,我正在寻找标准库函数或类似的东西,以便在C代码中执行此操作。

有人可以帮帮我吗?

注意:我知道这是一个非常基本的问题,但是在 SO 中找不到任何关于它的特别之处,所以如果它是一个重复的问题,请指出正确的线程,我会很高兴地删除这个问题。

4

2 回答 2

4

您可以使用Cygwin API Referencecygwin_conv_path中记录的函数来做到这一点。

于 2013-05-01T09:53:27.547 回答
0

这是我在研究 cygpath 源代码时提出的代码(它是用 C++ 编写的,所以根据我的需要对其进行了一些修改)

#include <windows.h>
#include <windef.h>
#include <sys/cygwin.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <glib-2.0/glib.h>

int conv_dos_path(char *filename, int absolute_flag, char *converted_path) {

    char *buf = NULL, *tmp;
    wchar_t *buf2 = NULL;
    DWORD len = 32768;
    ssize_t err;
    int print_tmp = 0;
    cygwin_conv_path_t conv_func = CCP_POSIX_TO_WIN_W
            | (absolute_flag ? CCP_ABSOLUTE : CCP_RELATIVE);

    if (!filename || !filename[0]) {
        puts("Can't convert empty path");
        return 0;
    }

    buf = (char *) g_try_malloc(len);
    buf2 = (wchar_t *) g_try_malloc(len * sizeof(wchar_t));
    if (buf == NULL) {
        puts("Out of memory error.");
        return 0;
    }

    err = cygwin_conv_path(conv_func, filename, (void *) buf2, len);
    if (err) {
        puts("Error while converting path.");
        return 0;
    }
    wcstombs(buf, buf2, 32768);
    tmp = buf;
    if (strncmp(buf, "\\\\?\\", 4) == 0) {
        len = 0;
        if (buf[5] == ':')
            len = 4;
        else if (!strncmp(buf + 4, "UNC\\", 4))
            len = 6;
        if (len && strlen(buf) < PATH_MAX + len) {
            tmp += len;
            if (len == 6)
                *tmp = '\\';
            print_tmp = 1;
        }
    }

    converted_path = memcpy(converted_path, tmp, strlen(tmp) + 1);
    if (buf2)
        g_free(buf2);
    if (buf)
        g_free(buf);

    return 1;
}

char* get_real_path(char* filename){
    char actualpath[PATH_MAX + 1];
    char *ptr, *real_path;

    ptr = realpath(filename, actualpath);
    if(ptr == NULL){
        char buf[256];
        strerror_r(errno, buf, 256);
        puts(buf);
        return NULL;
    }
    real_path = (char*)g_malloc(strlen(ptr));
    conv_dos_path(ptr, 1, real_path);
    return real_path;
}


int main(int argc, char *argv[]) {
    g_setenv("CYGWIN", "nodosfilewarning", 1);
    char* path = get_real_path(argv[1]);
    if(path)
        puts(path);
    g_free(path);
    return 0;
}
于 2013-05-01T10:41:47.810 回答