1

I'm trying to create a new string, using sprintf_s from a WCHAR. My code looks like:

#include <stdio.h>
#include <Windows.h>
void main(int argc, char ** argv) {
    TCHAR header[200];
    TCHAR* uuid = L"4facda65-5b27-4c70-b7d4-58c57b87682a";
    sprintf_s(&header, 200, "Client-ID: %ws\n", uuid);
    printf("UUID: %ws\n", uuid);
    printf("Header: %ws\n", header);
}

How come header is printed as Header: and not as Header: 4facda65-5b27-4c70-b7d4-58c57b87682a.

I just can't seem to figure out what I'm doing wrong.

EDIT: Tim Randall's link helped me on my way to a solution that works. Replacing the sprintf_s line with swprintf(header, sizeof(header) / sizeof(*header), L"Client-ID: %ws\n", uuid); seems to work.

Still, I'm unsure why this works, and why sprintf_s didn't?

MadsRC
  • 197
  • 1
  • 12
  • This might help https://stackoverflow.com/questions/14172886/using-wsprintf-to-convert-int-to-wchar-t – Tim Randall Nov 02 '18 at 20:10
  • 3
    MSVC compiler output gives many warnings which are intended to help you. – Weather Vane Nov 02 '18 at 20:12
  • TCHAR not always wchar_t. Did you compile with UNICODE? – jwdonahue Nov 02 '18 at 20:14
  • TimRandall - Thanks, reading it now. WeatherVane - My MSVC doesn't give me any warnings here. jwdonahue - I think I did :D Sorry for my newb'ness, but I'm totally new to developing on a MS platform... Literally just downloaded MSVC2017 Community Edition on Win10 and started playing. Edit: Just checked, My project Character Set is set to unicode. – MadsRC Nov 02 '18 at 20:17
  • 1
    `TCHAR` is an outdated, unneeded macro. There's no point in using it at all, but in particular there's no point if you're hard-coding `printf` format strings to use `%ws`. – Carey Gregory Nov 02 '18 at 20:29
  • [godbolt](https://gcc.godbolt.org/z/ML3Ewg) says `[x86 MSVC 19 2017 RTW #1] error C2664: 'int sprintf_s(char *const ,const ::size_t,const char *const ,...)': cannot convert argument 1 from 'wchar_t (*)[200]' to 'char *const '`. `sprintf_s` writes to a char buffer, but you gave it a wchar_t buffer. – Raymond Chen Nov 02 '18 at 20:31
  • @CareyGregory - I'm sorry, but the MSDN "Get started" guide i looked at used TCHAR, and I saw it had been updated this year so I thought it was okay to use. Should I just specify wchar directly? The printf statements was purely for debugging. – MadsRC Nov 02 '18 at 20:39
  • @MadsRC Yes. The getting started guide was probably written 10 years ago. Just use wchar directly. – Carey Gregory Nov 02 '18 at 20:40
  • 1
    I don't see how that code could even compile. Either `TCHAR` is `wchar_t` in which case `sprintf_s` would complain because it's expecting a `char*` for the first argument, or `TCHAR` is `char` in which case `TCHAR* uuid = L"...";` would complain because you're trying to assign a wide string literal to a `char*` pointer. – Jonathan Potter Nov 02 '18 at 21:02
  • @jon: This is C. A pointer is just a pointer. The compiler won't complain (unlike a C++ compiler). – IInspectable Nov 03 '18 at 13:37
  • @IInspectable oops didn't look at the tag. – Jonathan Potter Nov 04 '18 at 07:36

1 Answers1

3

Just use the functions intended to process or print wchar_t strings and explicitly defined wide-character strings:

WCHAR header[200];
WCHAR* uuid = L"4facda65-5b27-4c70-b7d4-58c57b87682a";
swprintf_s(header, 200, L"Client-ID: %s\n", uuid);
wprintf(L"UUID: %s\n", uuid);
wprintf(L"Header: %s\n", header);

See also: Is TCHAR still relevant?

Note also that you just pass header as the string to be written to, not &header.

Govind Parmar
  • 20,656
  • 7
  • 53
  • 85