POSIX到DOS和DOS到POSIX路径转换在C中

时间:2013-04-28 17:06:55

标签: c gcc cygwin posix dos

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

有人可以帮帮我吗?

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

2 个答案:

答案 0 :(得分:4)

您可以使用Cygwin API Reference中记录的cygwin_conv_path函数执行此操作。

答案 1 :(得分: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;
}