В чем проблема следующего преобразования из argv [1] в строку char *? - PullRequest
1 голос
/ 09 января 2020

Я очень плохо знаком с C и указателями. Я пытаюсь преобразовать аргумент командной строки в wchar_t *. Но почему-то это не дает должного результата. Чего мне не хватает?

void fun(){
    std::setlocale(LC_ALL, "en_US.utf8");
    std::wcout.imbue(std::locale("en_US.utf8"));
    char* mbstr = "f:\\mypath1\\mypath2\\mypath3";
    wstring reposPath;
    char *c_ReposPathString = (char*)mbstr;
    size_t c_ReposPathStringSize= 0;
    if(c_ReposPathString)   
    {       
         c_ReposPathStringSize = 2*(strlen(c_ReposPathString)+1);   
    }
    wchar_t *w_ReposPathChar = new wchar_t[c_ReposPathStringSize];  
    if(w_ReposPathChar) 
    {       
       mbstowcs(w_ReposPathChar, c_ReposPathString, c_ReposPathStringSize);
    }
       reposPath = w_ReposPathChar;

    printf("%s",  (char *)reposPath.c_str());
    free(w_ReposPathChar);
}

, когда я печатаю длину w_path, он показывает 1. But argv[1] имеет более одного символа.

1 Ответ

0 голосов
/ 09 января 2020

Вы не можете просто повторно привести строку wchar_t к строке char и ожидать, что она будет работать, поскольку может (будет) быть много wchar_t значений, которые имеют свои верхние Байт как ноль (который будет рассматриваться как терминатор после приведения).

Итак, вместо:

printf("%s",  (char *)reposPath.c_str());

, который видит «ложный» нуль-терминатор после f, просто напечатайте строку wchar_t, чтобы узнать, что это такое:

printf("%ws", reposPath.c_str());

Кроме того, в вашем объявлении mbstr отсутствует const, которое должно быть следующим:

const char* mbstr = "f:\\mypath1\\mypath2\\mypath3";

и вам не нужно выделять удвоенное число char для вашего wchar_t буфера, так что этого будет достаточно:

    if (c_ReposPathString)
    {
        c_ReposPathStringSize = strlen(c_ReposPathString) + 1; // Don't need "* 2"
    }

Не стесняйтесь просить дальнейших разъяснений и / или объяснение.

...