2013-07-28 65 views
1

我试图实现函数,它将char *转换为wchar_t *。但问题是,wprintf显示不同的结果。我究竟做错了什么?char * to wchar_t *函数实现

wchar_t *toWchar(char *data) 
{ 
    if(!data) 
    { 
     return NULL; 
    } 

    int size = strlen(data); 
    if(!size) 
    { 
     return NULL; 
    } 

    char *temp = (char *)malloc(size * 2); 
    if(!temp) 
    { 
     return NULL; 
    } 

    int j = 0; 
    for(int i = 0; i < size; i++) 
    { 
     temp[j++] = data[i]; 
     temp[j++] = '\0'; 
    } 

    return (wchar_t *)temp; 
} 

编辑: 主要功能:

int main() 
{ 
    wchar_t *temp = toWchar("hello, world!"); 
    if(temp) 
     wprintf("%ls\n", temp); 
    return 0; 
} 
+2

你使用的是什么编码?什么编码字符,什么编码wchar_t?你的代码可以工作,如果字符是ASCII。并且请注意,您需要添加一个空终止符。 –

+0

呜呜,这么多问题!你能给我一些提示怎么办?我只是编程的初学者,我不知道我使用的是哪种编码。如果这些信息对您有帮助,我在Linux机器上使用普通英语作为语言环境。 – user2399415

+0

你需要弄清楚你使用的是什么编码。你为什么要转换为wchar_t?你为什么不使用库函数? –

回答

2

作为起点; GCC会给你依赖于平台的WCHAR类型/尺寸如下:

echo "" | gcc -E - -dM | grep WCHAR 

#define __WCHAR_MAX__ 2147483647 
#define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1) 
#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 
#define __WCHAR_TYPE__ int 
#define __SIZEOF_WCHAR_T__ 4 

A resource表明:

“C和C++介绍固定大小的字符类型char16_t和char32_t在它们各自的标准2011修订版以提供16位和32位Unicode转换格式的明确表示,并保留wchar_t实现定义。“

+0

该死的..我虽然wchar_t是2个字节:(我怎样才能使用平台无关的编码? – user2399415

+0

@ user2399415编辑建议你不同的类型:如char16_t或char32_t ' – sgun

+0

非常感谢!jamesdlin的帖子也非常有用:-) – user2399415

1

这里有几个明显的问题:

  1. 你不是一个NUL终止符分配空间。

  2. 你假设wchar_t是2个字节,这不一定是真的。在许多Linux系统上,它可能代表一个长度为4个字节的UTF-32代码单元。

  3. 你假设你正在使用一个小端架构,这也不一定是真实的(虽然它可能是真的)。

  4. 您打电话格式字符串,但wprintf()预计const wchar_t*参数。编译器应该已经产生了一个关于这个的错误。 (你记得要加#include <wchar.h>(对于C)或#include <cwchar>(对于C++)?)

假设这意味着仅在ASCII投入工作,你可以通过做解决这些问题:

int size = strlen(data) + 1 /* NUL */; 
... 

// Allocate a wchar_t buffer directly. 
// Note that the cast below is necessary in C++ but not in C. 
wchar *temp = (wchar_t *)malloc(size * sizeof *temp); 
... 
int j = 0; 
for(int i = 0; i < size; i++) 
{ 
    temp[j++] = data[i]; 
} 

,然后当你打电话wprintf,使用方法:

wprintf(L"%ls\n", temp); // Note the L prefix to the string literal. 

另外,不要忘记调用free(temp)时,即可大功告成。

+0

typo:'wchar * temp' - >'wchar_t * temp' – dyp

+0

* Ahem *,我试图将单字节字符转换为双字节字符(我理解'unicode'这样的关键词。)例如'a'变成'a \ x00',因为我使用的一些关键字长度是两个字节,不仅仅是ASCII :) – user2399415

+1

@ user2399415:你的原始代码试图只填充零字节的字符,这只适用于ASCII字符。如果您需要处理其他编码,您将:1.找出您正在处理的哪些*编码,以及2.编写一个解码器(或者最好使用现有的库)。 – jamesdlin