Почему нельзя конвертировать TCHAR * в char * - PullRequest
8 голосов
/ 18 февраля 2010

ошибка C2664: 'strcpy': невозможно преобразовать параметр 1 из 'TCHAR *' в 'char *' код:

LPCTSTR name, DWORD value
strcpy (&this->valueName[0], name);

ошибка C2664: «strlen»: невозможно преобразовать параметр 1 из «LPCTSTR» в «const char *»

LPCTSTR name; 
strlen (name)     

Приведенный выше код для класса, который отлично работает в другом проекте, я не могу найти причину, почему он не работает в этом проекте MS VS2010.

Ответы [ 4 ]

13 голосов
/ 18 февраля 2010

Вам нужно использовать такую ​​функцию, как wcstombs , когда определено _UNICODE. Либо это, либо просто используйте _tcslen (см. Общие текстовые регулярные сопоставления ) в строке TCHAR, и компилятор переведет ее в strlen или wcslen в зависимости от того, используете ли вы юникод или нет .

7 голосов
/ 18 февраля 2010

Возможно, потому что TCHAR определен как char в одном из ваших проектов, но не в VS2010, где он, вероятно, wchar_t.

Если ваш проект определяет UNICODE / _UNICODE, что аналогично указанию его в качестве сборки Unicode в настройках проекта, TCHAR будет иметь значение wchar_t.

В основном вам нужно решить, использовать ли Юникод или нет, и если вы это сделаете, вам нужно изменить обычные вызовы strncpy и др. На эквиваленты с широким символом или использовать t-варианты, которые меняются так же, как и TCHAR , Посмотрите на справку для strncpy или других функций, чтобы увидеть, как называются широкие или t-варианты.

Вы также можете посмотреть в MSDN вызовы, такие как strcpy , где вы можете увидеть, что версия с широким символом называется wcscpy, а версия t называется _tcscpy. Я бы порекомендовал вам придерживаться t-версий, если вы собираетесь использовать код в разных проектах, которые используют UNICODE или нет, или принять информированное решение о том, какой из них вы собираетесь использовать, а затем придерживаться этого. Что лучше, зависит от вашего сценария, я бы сказал, и может ссылаться на некоторые "религиозные" мнения ...

4 голосов
/ 16 ноября 2012

Вот код, который поможет вам, он был первоначально размещен на www.wincli.com/?p=72, но здесь я заключил его в небольшой класс:)

class char_args
{
private:
char **l_argn;
int arg_num;

int wstrlen(_TCHAR * wstr)
{
    int l_idx = 0;
    while (((char*)wstr)[l_idx] != 0) l_idx += 2;
    return l_idx;
}

// Allocate char string and copy TCHAR->char->string
char *wstrdup(_TCHAR *wSrc)
{
    int l_idx = 0;
    int l_len = wstrlen(wSrc);
    char *l_nstr = (char *)malloc(l_len);
    if (l_nstr) {
        do {
            l_nstr[l_idx] = (char)wSrc[l_idx];
            l_idx++;
        } while ((char)wSrc[l_idx] != 0);
    }
    l_nstr[l_idx] = 0;
    return l_nstr;
}

char_args & operator=(const char_args&); // does not allow assignment of class
char_args(const char_args&); // does not allow copy construction

public:
char_args(int argcc, _TCHAR* argv[]) : arg_num(argcc)
{
    l_argn = (char **)malloc(argcc *sizeof(char*));
    for (int idx = 0; idx < argcc; idx++) l_argn[idx] = wstrdup(argv[idx]);
}

~char_args()
{
    for(int idx = 0; idx < arg_num; idx++) if (l_argn[idx]) free(l_argn[idx]);
    free(l_argn);
}

const char * operator[](const int &i)
{
    if (i < arg_num) return l_argn[i]; else return 0;
}

const int argc() { return arg_num; }
};

Вот демонстрация использования кода:

int _tmain(int argc, _TCHAR* argv[])
{
  char_args C_ARGV(argc, argv);
  for(int i = 0; i  < C_ARGV.argc(); i++) cout << C_ARGV[i] << endl;
}
4 голосов
/ 18 февраля 2010

Является ли ваш проект проектом Unicode? Если так, то я считаю, что TCHAR будет эквивалентно wchar_t, а не char, что сделает ваши попытки преобразования недействительными. Подробнее см. Здесь .

...