为什么无法将TCHAR*转换为char*?

10

错误 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个回答

15

当定义了_UNICODE时,你需要使用这样的函数,如wcstombs。或者只需在TCHAR字符串上使用_tcslen(参见通用文本例程映射),编译器将会根据是否使用Unicode来转换为strlen或wcslen。


1
那篇文章刚好为我节省了几个小时。新的C++项目默认使用Unicode字符集,将其关闭后,这些错误得到了修复。 - Scott P

8
可能是因为在你的某个项目中TCHAR被定义为char,但在VS2010中可能被定义为wchar_t。
如果你的项目定义了UNICODE / _UNICODE,这与在项目设置中指定它为Unicode构建相同,那么TCHAR将是wchar_t。
基本上,你需要决定是否使用Unicode,如果使用,你需要将常规调用strncpy等更改为宽字符等效项或使用t-变量,这些变量与TCHARs的更改方式相同。查看strncpy或其他函数的帮助以查看广泛或t变量的名称。
你还可以查看MSDN中的调用,例如strcpy,在那里你可以看到宽字符版本称为wcscpy,t版本称为_tcscpy。如果你要在不同的使用UNICODE或不使用UNICODE的项目中使用代码,我建议你坚持使用t版本,或者做出明智的决定并坚持使用它。哪个更好取决于你的情况,可能会引发一些“宗教”观点...

@Christoferw:我更新了我的答案,给你一个解决这个问题的指针。如果你需要更多帮助,请再写一条评论。 - villintehaspam

4

这里有一些代码可以为您解决问题,它最初发布在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

你的项目是否是Unicode项目?如果是,我相信TCHAR将等同于wchar_t而不是char,这将使你的转换尝试无效。更多信息请见此处


它在Visual Studio的项目设置中被选中: 字符集:使用多字节字符集 - Christoferw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接