C Returned char from GetSaveFileName() contains null characters

2

I'm using the following code to get the filepath to save to for use with tinyxml2:

OPENFILENAME ofn;

char szFileName[MAX_PATH] = "";

ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn); 
ofn.hwndOwner = NULL;
ofn.lpstrFilter = (LPCWSTR)L"XML Files (*.xml)\0*.xml\0All Files (*.*)\0*.*\0";
ofn.lpstrFile = (LPWSTR)szFileName;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
ofn.lpstrDefExt = (LPCWSTR)L"xml";
GetSaveFileName(&ofn);

This works fine and displays the Dialog box however when I look up the returned value in szFileName it seems to contain many null characters:

szFileName  0x0026f5b0 "C"  char[0x00000104]
[0x00000000]    0x43 'C'    char
[0x00000001]    0x00 '\0'   char
[0x00000002]    0x3a ':'    char
[0x00000003]    0x00 '\0'   char
[0x00000004]    0x5c '\\'   char
[0x00000005]    0x00 '\0'   char
[0x00000006]    0x61 'a'    char
[0x00000007]    0x00 '\0'   char
[0x00000008]    0x73 's'    char
[0x00000009]    0x00 '\0'   char
[0x0000000a]    0x64 'd'    char
[0x0000000b]    0x00 '\0'   char
[0x0000000c]    0x61 'a'    char
[0x0000000d]    0x00 '\0'   char
[0x0000000e]    0x73 's'    char
[0x0000000f]    0x00 '\0'   char
[0x00000010]    0x64 'd'    char
[0x00000011]    0x00 '\0'   char
[0x00000012]    0x61 'a'    char
[0x00000013]    0x00 '\0'   char
[0x00000014]    0x73 's'    char
[0x00000015]    0x00 '\0'   char
[0x00000016]    0x2e '.'    char
[0x00000017]    0x00 '\0'   char
[0x00000018]    0x78 'x'    char
[0x00000019]    0x00 '\0'   char
[0x0000001a]    0x6d 'm'    char
[0x0000001b]    0x00 '\0'   char
[0x0000001c]    0x6c 'l'    char

This when passed into tinyxml2 ends up saving a file with which the name is 1 character long, and the first char in szFileName.

Why would it be adding in these null characters after each character?

c++
char
savefiledialog
asked on Stack Overflow Apr 3, 2013 by Shane Smith

2 Answers

3

You are calling GetSaveFileNameW instead of GetSaveFileNameA. Declare szFileName as array of TCHAR (or WCHAR).

The name GetSaveFileName will resolve to the name GetSaveFileNameW or GetSaveFileNameA depending on the #define in your code (or project settings). By default it defines _UNICODE ("wide charaters") in modern Visual Studio versions.

If you pass it on to another library that expects a certain character set, you may have to convert using WideCharToMultiByte or related functions.

Also: don't forcibly coerce one type into an incompatible different type like you do with szFileName (being char[MAX_PATH]) and (LPWSTR).

answered on Stack Overflow Apr 3, 2013 by 0xC0000022L • edited Apr 3, 2013 by 0xC0000022L
0

I'm no professional of the Win32 API, but :

ofn.lpstrFile = (LPWSTR)szFileName;

You are using a LPWSTR, which is a "32-bit pointer to a string of 16-bit Unicode characters". That means each character is encoded over two bytes. Since ASCII character values fit on a single byte, I'm going to assume the second one is always going to be set to 0.

answered on Stack Overflow Apr 3, 2013 by Nbr44

User contributions licensed under CC BY-SA 3.0