file — Конкатенация LPTSTR с const char * (Win32 C ++)

Я хочу иметь возможность открыть файл в моем приложении Win32.
Метод, который я использую, — это получение корневого пути из поля редактирования, например, «C: \ MyFolder» (это назначено strPathToSource). Затем я хочу добавить еще одну строку, например «\ source \ Utilities \ File.h» и сохраните объединенный путь в новой переменной strPathToFile,

Так strPathToFile должен содержать «C: \ MyFolder \ source \ Utilities \ File.h», который затем можно открыть с помощью infile.open(strPathToFile),

Соответствующий код показан ниже:

ifstream infile;

int bufSize = 1024;
LPTSTR strPathToSource = new TCHAR[bufSize];
GetDlgItemText(hWnd, IDC_MAIN_EDIT_FILEPATH, strPathToSource, bufSize); // Get text from edit box and assign to strPathToSource

const char* strPathToFile = char(strPathToSource) + PATH_TO_FILE;
infile.open(strPathToFile);
if(!infile)
{
log(hWnd, "File.h not found.");
return false;
}

куда PATH_TO_FILE определяется как:

const char* PATH_TO_FILE = "\\source\\Utilities\\File.h";

Моя проблема заключается в том, что он всегда выходит из системы «File.h not found». Я считаю, что проблема заключается в конкатенации, например,

const char* strPathToFile = char(strPathToSource) + PATH_TO_FILE;

Проходя через, я вижу значения strPathToSource а также PATH_TO_FILE как и должно быть, но объединенный результат в strPathToFile Я считаю, что это значение NULL.

1

Решение

Добавление двухсимвольных указателей не объединяет строки, а просто добавляет два значения указателя (как «числа»). Таким образом, вы получите неверный указатель.

Кроме того, преобразование типов из LPTSTR в char * не является хорошей идеей, поскольку TCHAR также может быть широким символом, в зависимости от текущих настроек сборки.
(на самом деле вы приводите LPTSTR к символу, а не к указателю, что еще более неправильно)

Я думаю, что проще всего было бы преобразовать обе строки в std :: string (или wstring), там вы можете использовать оператор ‘+’ для конкатенации.

Одна возможность сделать это:

const std::wstring strPathToFile = cvt2wstring(strPathToSource) + cvt2wstring(PATH_TO_FILE);

cvt2wstring определяется как:

#include <codecvt>
#include <string>

std::wstring cvt2wstring(const char * str)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t> > converter;
return converter.from_bytes(str);
}

std::wstring cvt2wstring(const wchar_t * str)
{
return str;
}

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

Для обратного преобразования в std :: string (чтобы вы могли использовать обычный std :: ifstream) вы можете переключить направление:

std::string cvt2string(const char * str)
{
return str;
}

std::string cvt2string(const wchar_t * str)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t> > converter;
return converter.to_bytes(str);
}

Для меня ifstream :: open (), кажется, работает с wstring (но это может быть расширение MSVC, поскольку стандарт C ++ этого не обеспечивает — в любом случае, если вы используете TCHAR & сост. Вы, вероятно, нацелены на Windows и MSVC).

2

Другие решения

Мартин Боннер в основном дал правильный ответ.

Короче говоря, лучшее решение — игнорировать TCHAR вчистую. Это костыль, созданный в последнее десятилетие прошлого века, когда Unicode был проблемой для ПК с 4 МБ ОЗУ. Сегодня распространено 4 ГБ, в тысячу раз больше.

Однако, если вы все еще хотите жить в эту эпоху, будьте последовательны. Не определять

const char* PATH_TO_FILE = "\\source\\Utilities\\File.h";

но использовать

const TCHAR * PATH_TO_FILE = _T("\\source\\Utilities\\File.h");

Также научитесь использовать конкатенацию строк. Ты можешь использовать std::basic_string<TCHAR>::operator+ (легко) или tcscat (привыкнуть к переполнению буфера).

1

По вопросам рекламы [email protected]