为什么vsnwprintf不能将普通字符串转换为宽字符串?

时间:2011-10-31 14:13:51

标签: c++ c

以下代码不会产生预期的输出。为什么呢?


    wchar_t* wchar_t_printf_return(wchar_t* formatstring, ...){
        va_list argp;
        va_start(argp, formatstring);
        int templen = 256;
        templen = vsnwprintf(NULL, 0, formatstring, argp)+3;
        wchar_t *buffer = (wchar_t *) malloc ((templen+1)*sizeof(wchar_t));
        memset(buffer, 0, (templen+1)*sizeof(*buffer));
        int retval;
        while ((retval = vsnwprintf(buffer, templen, formatstring, argp)) == -1 || (retval >= (templen-1))){
            templen = templen << 1;
            buffer = (wchar_t *) realloc (buffer, (templen+1)*sizeof(wchar_t));
            va_end(argp);
            va_start(argp, formatstring);
        }
        va_end(argp);
        buffer[templen] = L'\0';
        return buffer;
    }

    int main(){
        int i;
        char *id = "2923BE84E16CD6AE529049F1F1BBE9EB";
        wchar_t *val = wchar_t_printf_return(L"'%s'", id);
        printf("%ls\n", val);
    }

编辑:更具体地说,main中的printf应该将id包装在两个单引号中,从而输出:'2923BE84E16CD6AE529049F1F1BBE9EB'。这里主要的目的是说明函数中的错误,不再是。该函数应该是printf族函数的替代函数,它将结果返回到新分配的缓冲区而不是预先存在的缓冲区。这是在cygwin中运行的,通过gcc-3本地编译,带有-mno-cygwin选项(aka mingw)。抱歉混乱!

2 个答案:

答案 0 :(得分:3)

%s说明符会根据您使用的是printf还是wprintf系列函数来更改含义。 When used with a wprintf family function, the %s specifier indicates a wide string,但是你正在传递一个很窄的字符串。您需要%hs说“这是一个很窄的字符串。”

(你似乎意识到这一点,因为你使用%ls来打印一个带有printf - 家庭功能的宽字符串,但是当你走另一条路的时候,你却忘了它。)

答案 1 :(得分:1)

尝试使用%S进行翻译,而不是%s。