Fix
// enable / disable both of them to enable/disable unicode
//#define UNICODE
//#define _UNICODE
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
int main(int argc, char* argv[]){
WIN32_FIND_DATA search_data;
memset(&search_data, 0, sizeof(WIN32_FIND_DATA));
HANDLE handle = FindFirstFile(TEXT("c:\\*"), &search_data);
FILE *directorycontents = fopen("C:\\testwrite.txt", "wb");
while(handle != INVALID_HANDLE_VALUE)
{
fwrite(search_data.cFileName, 1, _tcslen(search_data.cFileName) * sizeof(TCHAR), directorycontents);
_fputts(TEXT("\r\n"), directorycontents);
if(FindNextFile(handle, &search_data) == FALSE)
break;
}
}
Other problems
search_data.cFileName += newline;
This line is problematic because the type of cFileName
is TCHAR[]
(a TCHAR array) and the type of newline
is wstring
. These types are not compatible.
You can not append to a fixed size array using the +=
operator.
cstr(search_data.cFileName)
This has no meaning. The function cstr can only be used on types of string
objects.
Learn more about null-terminated strings
http://en.wikipedia.org/wiki/Null-terminated_string
cFileName
is a null-terminated string. So for example when TCHAR is char
(_UNICODE not defined) then the string "Hello" looks like this in memory:
['H','e','l','l','o', '\0', ...]
Here each element takes one byte, the ...
can be any junk. cFileName
always has the capacity of 260 elements, but this doesn't mean the lenght of the string inside cFileName is 260 long. Actually the maximal length of the string inside cFileName is 259, because you always must have a terminating '\0' element.
Learn more about TCHAR
http://www.codeproject.com/Articles/76252/What-are-TCHAR-WCHAR-LPSTR-LPWSTR-LPCTSTR-etc
TCHAR cFileName[MAX_PATH]; //this is how cFileName is defined
sizeof(TCHAR) == 2 // when _UNICODE is defined
sizeof(TCHAR) == 1 // when _UNICODE is defined
TCHAR
iswchar_t
(2 bytes) when_UNICODE
is definedTCHAR
ischar
(1 byte) when_UNICODE
is not defined.MAX_PATH
is defined to260
- Therefore calling sizeof(cFileName) will give you 260 (when _UNICODE is not defined), or 520 (when _UNICODE is defined)
To get a length of a string which consists of TCHAR you have to use the _tcslen
macro. This macro expands to strlen
or wcslen
depending on the _UNICODE
define.
You have to know that the array cFileName
having the size of 260 does not mean that your string have the same length. cFileName
stores a C-style string (regardless of _UNICODE) meaning it terminates with a zero element in the array.
If you want to avoid using unicode, make sure that _UNICODE
is not defined before including windows.h
. You can also achieve this by setting the character set to "Not set" as shown in the article.
TCHAR has been in use to make it easier to compile unicode and non-unicode versions of the same program, just by toggling a define.
Conversion between wchar_t
and char
strings:
http://msdn.microsoft.com/en-us/library/5d7tc9zw.aspx
Learn more about the various string types
http://www.codeproject.com/Articles/2995/The-Complete-Guide-to-C-Strings-Part-I-Win32-Chara http://www.codeproject.com/Articles/3004/The-Complete-Guide-to-C-Strings-Part-II-String-Wra