2016-03-16 2 views
0

Я читал, что для получения пути AppData можно использовать SHGetSpecialFolderPath();. Однако он возвращает массив TCHAR. Мне нужно иметь std::string.Как получить% AppData% путь как std :: string?

Как его можно преобразовать в std::string?

Update

Я читал, что можно использовать getenv("APPDATA"), но он не доступен в Windows XP. Я хочу поддержать Windows XP - Windows 10.

+0

SHGetSpecialFolderPath не поддерживается с Windows 2000 согласно msdn, как насчет использования SHGetFolderPath? https://msdn.microsoft.com/en-us/library/windows/desktop/bb762181(v=vs.85).aspx Если вам нужно принудительно ввести тип кодирования, в winapi у вас обычно есть окончания с W для wchar_t , A для символа. Такие, как SHGetFolderPathA. Это нужно поддерживать с Win 2000 до сегодняшнего дня, даже если он установлен для устаревания. – Geries

ответ

1

Тип T означает, что SHGetSpecialFolderPath является пара функций:

  • SHGetSpecialFolderPathA для Windows, ANSI кодируются char на основе текста, и

  • SHGetSpecialFolderPathW для UTF-16 закодирован wchar_t на основе текста, Windows '“ Юникод ”.

Вариант ANSI является просто оболочкой для варианта Unicode, и он не может логически произвести правильный путь во всех случаях.

Но это то, что вам нужно использовать для данных на основе char.


Альтернативы является использование широкого варианта функции, и использовать любые машины, которые вы комфортно преобразовать широкий текстовый результат в байтах-ориентированные char на основе кодирования по вашему выбору, например, UTF-8.

Обратите внимание, что строки UTF-8 нельзя использовать непосредственно для открытия файлов и т. Д. Через API Windows, поэтому этот подход требует еще большего преобразования только для использования строки.


Однако я рекомендую переключиться на широкий текст в Windows.

Для этого определите макрокоманду UNICODE, прежде чем включать <windows.h>.

Это также значение по умолчанию в проекте Visual Studio.

+0

Какое влияние оказывает на мой проект переход к широкому тексту? В настоящее время он настроен как «Использовать многобайтовый набор символов». – Z0q

+0

@ Z0q: Литералы и строки в вызовах API-функций должны быть изменены на широкие. В основном это просто префикс 'L'. Например, если с ANSI у вас есть «привет», с Unicode у вас есть «L» Hello ». –

+0

Если я называю 'fopen()' например, как я могу отправить широкий текст в качестве параметра? – Z0q

1

Вы должны использовать SHGetSpecialFolderPathA(), чтобы явно работать с символами ANSI.

Затем просто преобразуйте массив char в std::string, как обычно.

/* to have MinGW declare SHGetSpecialFolderPathA() */ 
#if !defined(_WIN32_IE) || _WIN32_IE < 0x0400 
#undef _WIN32_IE 
#define _WIN32_IE 0x0400 
#endif 

#include <shlobj.h> 
#include <string> 

std::string getPath(int csidl) { 
    char out[MAX_PATH]; 
    if (SHGetSpecialFolderPathA(NULL, out, csidl, 0)) { 
     return out; 
    } else { 
     return ""; 
    } 
} 
0

Typedef Строка или как станд :: строка или станд :: wstring в зависимости от конфигурации вашей компиляции. Может понадобиться следующий код:

#ifndef UNICODE 
    typedef std::string String; 
#else 
    typedef std::wstring String; 
#endif