2012-02-01 3 views
0

Я иду с фона C#, и мой C++ очень ржавый, поэтому, пожалуйста, несите меня.Синтаксис указателя строки, это правильно?

Следующее определение функции принимает указатели (LPTSTR) на строки, представляющие входное имя файла (szIn) и имя выходного файла (szOut). Вот прототип функции:

ConvertFile(LPTSTR szIn, LPTSTR szOut); 

В настоящее время функция выполняется внутри некоторого кода пользовательского интерфейса, вот пример того, как имя выходного файла получается из указателя szOutput:

TCHAR szOutput[255]; // output filename 

if (g_szFilename[0] != 0) 
{ 
    SetDlgItemText(hMainDlg, IDC_EDIT_INPUT, g_szFilename); 
    _tcscpy(szOutput, g_szFilename); 
    TCHAR * szExt = _tcsrchr(szOutput, '.'); 
    if (szExt != NULL) *szExt = 0; 
    _tcscat(szOutput, _T(".png")); 
} 

Я хочу сделать что-то в этих строках:

TCHAR inputFilename[256]; 
TCHAR outputFilename[256]; 

inputFilename += "somefile.txt"; 
outputFilename += "someotherfile.txt"; 

char *inputPtr; 
char *outputPtr; 

inputPtr = inputFilename; 
outputPtr = outputFilename; 

ConvertFile(inputPtr, outputPtr); 

Является ли это правильным синтаксисом для вкуса Microsoft C++ в Visual Studio 2008?

+2

C и C++ - это два разных языка и делают это * очень * по-разному. На каком языке вы используете? –

+0

@BoPersson Я отредактировал, чтобы уточнить, что я использую C++ здесь, извините за путаницу. –

+0

«Чувство Microsoft C++ в Visual Studio 2008» - это просто C++ - почему это было бы иначе в любом случае (ошибки в модульном компиляторе)? Обратите внимание, что VC++ также компилирует язык под названием C++/CLI, возможно, это то, о чем вы говорите? Если это так, код, который вы показали, далек от идиоматического. – ildjarn

ответ

0

Нет, вы не можете конкатенировать такую ​​строку. Вы пытаетесь добавить const char[] на конец другого массива ... который даже не будет компилироваться. Вам нужно использовать _tcscat() или (еще лучше, поскольку вы добавили тег C++), std::basic_string<TCHAR>.

+0

Интересно ... было ли это мести вниз или что-то действительно не так? –

+0

Вы понижаете меня, а затем пишете тот же ответ? – LihO

+1

@LihO: Я ответил первым (проверьте время), и мой включает в себя правильный способ решения проблемы. –

0

Не совсем. Массивы TCHAR уже должны распадаться на указатели TCHAR, что и есть LPTSTR (a TCHAR*). Таким образом, вы не должны использовать указатели char*, если только функция не объявлена ​​для принятия LPCSTR. Короче говоря, вы можете напрямую использовать inputFilename и outputFilename.

Помимо этого незначительного вопроса, реальная проблема заключается в том, что += не будет работать (он попытается выполнить арифметику указателя, если что-нибудь, что совсем не то, что вы хотите). Вместо этого используйте _tcscat():

_tcscat(inputFilename, TEXT("somefile.txt")); 
// ... 

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

еще одна вещь: Вы никогда не инициализировать inputFilename и outputFilename - - Они должны быть инициализированы до некоторой строки, прежде чем вы сможете объединить их.

+3

Оригинальный вопрос был обновлен для ссылки на C++; этот ответ был предназначен для C.Пожалуйста, не делайте этого, если используете C++. – Cameron

1

Это незаконно:

inputFilename += "somefile.txt"; 
outputFilename += "someotherfile.txt"; 

Вы можете использовать _tcscpy() скопировать строки:

TCHAR inputFilename[256] = { 0 }; /* FYI, the '= { 0 }' initialises the array.*/ 
TCHAR outputFilename[256] = { 0 }; 

_tcscpy(inputFilename, "somefile.txt"); 

и использовать _tcscat() конкатенировать:

_tcscat(inputFilename, "another-bit.txt"); 

Вы можете затем перейти к ConvertFile():

ConvertFile(inputFilename, outputFilename); 

Нет необходимости создавать другой указатель на эти переменные (поскольку массивы будут распадаться на указатели).

EDIT:

После изменения языка вы можете использовать std::basic_string:

std::basic_string<TCHAR> inputFilename(TEXT("somefile.txt")); 
std::basic_string<TCHAR> outputFilename(TEXT("someotherfile.txt")); 

И вы можете выполнить конкатенацию, как вы изначально хотели:

inputFilename += TEXT("a-bit-more"); 

И использовать c_str() метод доступ к массиву внутренних символов для перехода на ConvertFile():

ConvertFile(inputFilename.c_str(), outputFilename.c_str()); 

Обратите внимание, что c_str() возвращает const, изменить ConvertFile() к (я сделать предположение, что ConvertFile() не изменяет буферы, передаваемые в):

ConvertFile(LPCTSTR szIn, LPCTSTR, szOut); 
4

Неа. строки C++ может делать то, что вы пытаетесь сделать:

// Since we don't know whether to use string or wstring, we're stuck 
// with basic_string<TCHAR> 
std::basic_string<TCHAR> inputFilename, outputFilename; 

// Note the TEXT macro...it makes sure your chars are TCHARs 
inputFilename += TEXT("somefile.txt"); 
outputFilename += TEXT("someotherfile.txt"); 

// basic_string::c_str() returns you a pointer suitable for C stuff 
// (since this is a string of TCHARs, we'll get a const TCHAR* back) 
ConvertFile(inputFilename.c_str(), outputFilename.c_str()); 

C символьные массивы не могут быть объединены, как это. Вам нужно будет использовать _tcscat или другие подобные функции.

+0

Или вы можете использовать 'std :: wstring', который также определяется как' std :: basic_string ';) – LihO

+1

@LihO: Тип, который использует псевдонимы' TCHAR', зависит от того, компилируете ли вы ANSI или Unicode. Во-вторых, вы используете 'std :: wstring', вы можете просто перебросить все макросы' TCHAR' и 'TEXT (« whatever »)' из окна, и просто скажите 'wchar_t' и' L 'что угодно «соответственно», потому что вы просто пожертвовали совместимостью с 8-битными символами. – cHao

+0

Да, многобайтовый набор символов ... 'TCHAR', определяемый как« char »... 16-разрядные символы по умолчанию намного лучше – LihO

Смежные вопросы