GetCurrentDirectory() - почему каждый 2ой байт в szPath это \0?

109
15 октября 2019, 08:30

Эта функция должна записывать в szPath путь, откуда был запущен бинарник. У меня она возвращает путь, но, каждый 2ой байт в szPath это \0 , в итоге код ниже не работает так как я хотел. Адрес запуска бинарника: C:\Пользователи\z\source\repos\ProjectName\Debug (автоматом многие проги заменяют пользователи на users сами, тут не знаю заменяет или нет)

char szPath[0x100];
GetCurrentDirectory(0x100,(LPWSTR)szPath);
Answer 1

1) Довольно странно вы задаете размер массива, вы же в жизни пользуетесь десятичными числами, наверное? Вообще WinAPI определяет специальный символ MAX_PATH который определяет максимальный размер файлового пути. Лучше использовать его.

2) Вы задаете буфер для ASCII строки, но используете его с UNICODE версией функции. Правильно будет писать:

char szPath[MAX_PATH];
::GetCurrentDirectoryA(MAX_PATH, szPath);

Однако этот код не вполне годится если в пути встречаются национальные символы. Поэтому лучше использовать строку UNICODE:

WCHAR szPath[MAX_PATH];
::GetCurrentDirectoryW(MAX_PATH, szPath);

3) И как вишенка на тортике - функция GetCurrentDirectory не возвращает путь к исполняемому файлу. Она возвращает текущий каталог, а это нечто другое. Он действительно чаще всего совпадает с каталогом запущенного .exe, но далеко не всегда. Собственно, GetCurrentDirectory это пережиток MS-DOS, в многозадачной системе с графическим интерфейсом понятие "текущий каталог" имеет мало смысла. Лучше вообще забудьте про эту функцию, не нужна она.

Для получения пути к своему .exe нужно использовать функцию GetModuleFileName. Например, так:

WCHAR szPath[MAX_PATH];
::GetModuleFileNameW(NULL, szPath, MAX_PATH);

Это немного упрощенно (лучше было бы проверять на ошибку), но работать будет. Для получения именно каталога нужно отыскать первый '\' с конца и отбросить имя файла. Например, так:

*wcsrchr(szPath, L'\\') = L'\0';
Answer 2

Так а что ж вы ожидали? Почему у вас в вызове GetCurrentDirectory стоит явное приведение szPath к типу LPWSTR? Очевидно потому, что без него код не компилировался. То есть ваш проект создан в режиме Unicode и GetCurrentDirectory возвращает результат в виде "широкой" строки из символов wchar_t. Именно эти "широкие" символы вы и наблюдаете.

Зачем вы вообще создали проект в режиме Unicode, если вы не собираетесь работать с "широкими" строками? Вам нужно работать с "широкими" строками или нет? Дальнейшие шаги зависят от ответа на этот вопрос.

READ ALSO
Иконка в Qt c++ [закрыт]

Иконка в Qt c++ [закрыт]

Хотел бы в свою программу добавить иконку, чтоб потом нажимая на нее открывалась руководствоПосле того как скачал, надо иконку button'а изменить,...

116
Вопросы по qtdesigner

Вопросы по qtdesigner

1) Какие плюсы и минусы compile-time и run-time обработкиui файлов?

82
Разница в размерах одинаковых структур

Разница в размерах одинаковых структур

Решил написать класс для манипуляции BMP изображениямиПоскольку мне не нравится стиль WinAPI кода решил переопределить структуры BITMAPFILEHEADER и BITMAPINFOHEADER,...

109
Как влиять на время отправки датаграммы

Как влиять на время отправки датаграммы

Есть qudpsocketЕсть два массива байт

104