Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't convert TCHAR* to char*

error C2664: 'strcpy' : cannot convert parameter 1 from 'TCHAR *' to 'char *' code:

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

error C2664: 'strlen' : cannot convert parameter 1 from 'LPCTSTR' to 'const char *'

LPCTSTR name; 
strlen (name)     

The code above to a class which works fine in another project, I can't find the reason why it doesn't work in this MS VS2010 Project.

like image 963
Christoferw Avatar asked Feb 18 '10 10:02

Christoferw


4 Answers

You need to use a function such as wcstombs when _UNICODE is defined. Either that or just use _tcslen (Look under Generic-Text Routine Mappings) on the TCHAR string and the compiler will transfer it to either strlen or wcslen depending if you are using unicode or not.

like image 69
Goz Avatar answered Oct 21 '22 01:10

Goz


Probably because TCHAR is defined to be a char in one of your projects, but not in the VS2010 one where it is probably wchar_t.

If your project defines UNICODE/_UNICODE, which is the same as specifying it to be a Unicode build in the project settings, TCHARs will be wchar_t.

You basically need to decide whether to use Unicode or not and if you do, you need to change the regular calls to strncpy et al to the wide-char equivalents or use the t-variants that change the same way as TCHARs do. Look at the help for strncpy or the other functions to see what the wide or t-variants are called.

You can also look at MSDN for the calls such as strcpy, where you can see that the wide-char version is called wcscpy and the t version is called _tcscpy. I would recommend you to stick with the t-versions if you are going to use the code in different projects that either use UNICODE or not, or to make an informed decision which one you are going to use and then stick with that. Which is better depends on your scenario I would say and may invoke some "religious" opinions...

like image 33
villintehaspam Avatar answered Oct 21 '22 01:10

villintehaspam


Is your project a unicode project? If so I believe TCHAR will be equivalent to a wchar_t rather than a char making your conversion attempts invalid. See here for more info.

like image 4
jkp Avatar answered Oct 21 '22 01:10

jkp


Here is some code that will do the trick for you, it was originally posted to www.wincli.com/?p=72 but here I encapsulated it into a small class :)

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; }
};

Here is a demonstration of use of the code:

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;
}
like image 4
Jan-Albert van den Berg Avatar answered Oct 20 '22 23:10

Jan-Albert van den Berg