none
Имя каталога, созданного с помощью CreateDirectory() и, кстати, заданное латиницей, показывается в проводнике Windows каракулями. RRS feed

  • Вопрос

  • В консольном приложении Visual C++ на MS VS 2013 для создания каталога использую следующий код:

    CreateDirectory(LPCWSTR("VFS_ROOT"), &My_Security_Attributes);
    Имя создаваемого каталога - VFS_ROOT, как видите, в латинице, а не в кириллице, но когда смотрю этот созданный каталог в проводнике русифицированной Windows 7 Максимальной, то имя этого каталога написано не латиницей, а каракулями. Почему? Что нужно сделать, что бы в средствах просмотра файлов и каталогов (например, в том же самом проводнике Windows) имя этого созданного каталога было в латинице?



    7 июня 2014 г. 13:24

Ответы

  • Не проще тогда совсем юникод выключить? Если Вы MFC в программе не используете, в свойствах проекта смените "набор символов" на "многобайтобую кодировку" или на "не задано".

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!


    • Изменено kosuke904 8 июня 2014 г. 12:17
    • Помечено в качестве ответа Purple_Apple 8 июня 2014 г. 12:38
    8 июня 2014 г. 12:16

Все ответы

  • Вы первым параметром функции что именно хотите передать? Что это за дикость LPCWSTR("...")? Я Вам уже советовал язык C++ учить. Преобразование константного указателя на ANSI-строку к указателю на строку Юникод. Что получится, как Вы думаете? Еще не те каракули. У меня студенты с экзамена за это вылетают. Вы же основ языка не знаете!

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!


    • Изменено kosuke904 7 июня 2014 г. 19:58
    7 июня 2014 г. 19:56
  • Так покажите, милый человек, как нужно правильно сделать. Если я без такого преобразования передаю функции первый аргумент, то в design-time появляется ошибка несоответствия типов. Вот, кстати, почему? ( В примерах действительно передаётся без преобразования, а у меня вот не получается.) Вы думаете, что мне очень интересно тратить время копаясь в форумах? На мне приложение висит. Извините.


    7 июня 2014 г. 20:54
  • "Копаться" нужно не в форумах, а в учебниках, справочниках и фирменной документации. Там истина :)

    К сути вопроса. Практически все функции WinAPI, принимающие строку в качестве параметра, существуют в 2-х экземплярах (ANSI и Unicode). Выбор функции определяется настройками проекта. По умолчанию используется Unicode. Следовательно, Вы должны передать такую строку

    L"...."

    Приведение типа не может "по волшебству" модифицировать содержимое памяти, на которую ссылается указатель.


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    • Помечено в качестве ответа Purple_Apple 8 июня 2014 г. 9:05
    • Снята пометка об ответе Purple_Apple 8 июня 2014 г. 10:26
  • Спасибо, kosuke904. Я сделал так:

    CreateDirectory(_T("VFS_ROOT"), &mySA);
    и теперь имя каталога создаётся нормально нормально.

  • Макрос _T делает исходный код универсальным. Если посмотрите его определение, увидите, что в случае Unicode он как раз и добавляет символ L к строке.

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

  • Слушайте, помогите ещё, пожалуйста с этим же. Я сейчас передаю в CreateDirectory в качестве первого аргумента переменную string. Я её иницилизирую строкой

    string Str1 = "ABCD";
    string path = Str1.substr(0, 2);

    Т.е. вызов сейчас такой:

    CreateDirectory(path, NULL);
    и у меня опять та же ошибка " Не существует функции преобразования из std::string в LPCWSTR".  _T() сейчас - не помогает. Скажите, пожалуйста, как надо сделать правильно в этом случае?


    8 июня 2014 г. 10:35
  • Вместо string используйте wstring. Это тоже самое, но из символов юникод. Инициализировать, естественно, нужно строкой юникод (L"...").

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    8 июня 2014 г. 10:38
  • Сейчас делаю так:

    string Str1 = "ABCD";
    string path = Str1.substr(0, 2);
    
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    std::wstring wide = converter.from_bytes(path);
    
    CreateDirectory(wide, NULL);
    
    
    
    
    
    
    
    И в итоге - история та же. Только теперь жалуется, что нет функции преобразования из std::wstring в LPCWSTR.
    8 июня 2014 г. 11:48
  • wstring str = L"ABCS";
    wstring path = str.substr(0,2);
    CreateDirectory(path.c_str(),...);
    


    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

    8 июня 2014 г. 11:54
  • Вот в том-то и дело, что wstring str = L"ABCS"; у меня не сделаешь, т.к. у меня эта переменная типа std::string "просверлилась" в приложении на очень большую глубину (просто когда делал - не думал, что обсуждаемая проблема вылезет). Сейчас делаю так:

    string Str1 = "ABCD";
    string path = Str1.substr(0, 2);
    
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    std::wstring wide = converter.from_bytes(path);
    
    LPCWSTR pth = wide.c_str();
    
    CreateDirectory(pth, NULL);
    Вроде ошибку не показывает.


     

    8 июня 2014 г. 12:11
  • Не проще тогда совсем юникод выключить? Если Вы MFC в программе не используете, в свойствах проекта смените "набор символов" на "многобайтобую кодировку" или на "не задано".

    Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!


    • Изменено kosuke904 8 июня 2014 г. 12:17
    • Помечено в качестве ответа Purple_Apple 8 июня 2014 г. 12:38
    8 июня 2014 г. 12:16
  • Мысль! Учту обязательно. Но раз уж сейчас применил конвертор, то посмотрю, как он будет работать. Если забарахлит, то выключу юникод.

    8 июня 2014 г. 12:38