The following code does not produce the expected output. Why?
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);
}
EDIT: to state more specifically, the printf in main should wrap the id in two single quotes thereby outputting: ‘2923BE84E16CD6AE529049F1F1BBE9EB’. The purpose of the main here is to illustrate the bug in the function, no more. The function is supposed to be an alternate of the printf family functions which return the result in a newly allocated buffer instead of a preexisting one. This is being run in cygwin compiled natively via gcc-3 with the -mno-cygwin option (aka mingw). Sorry for the confusion!
The
%sspecifier changes meaning depending on whether you are using aprintforwprintffamily function. When used with awprintffamily function, the%sspecifier indicates a wide string, but you’re passing a narrow string. You need%hsto say “This is a narrow string.”(You seemed to be aware of this because you use
%lsto print a wide string with aprintf-family function, but you somehow forgot about it when going the other way.)