1

I am trying to use WriteFile to write a simple text in a .TXT file. Here's my declaration:

// For WriteFile fuction
    BOOL writeFile;
    LPCVOID textToWrite = L"SakyLabs: Hello, MDE.";
    DWORD numberOfBytes = (DWORD)wcslen(textToWrite);
    DWORD numberOfBytesWritten;

numberOfBytes was based on Microsoft's example from here.

Next, the WriteFile function:

writeFile = WriteFile(createFile, textToWrite, numberOfBytes, &numberOfBytesWritten, NULL);

I am getting createFile from a previous CreateFileW call. Also, I am using Unicode functions.

WriteFile works, but I only get this part of the text written in the file:

S a k y L a b s :   H 

What am I doing wrong?

Sergio Calderon
  • 837
  • 1
  • 13
  • 32

1 Answers1

1

The problem is that you're creating a wide-charecter string L"...". Each WCHAR is two bytes long -- because Windows is using UTF-16 for wide strings. wcslen counts the number WCHAR elements in it rather than bytes.

Either multiply the string length by the size of a WCHAR:

DWORD numberOfBytes = (DWORD)wcslen(textToWrite)*sizeof(WCHAR);

or use narrow char strings (preferably UTF-8 encoded if you actually use non-ASCII):

LPCVOID textToWrite = "SakyLabs: Hello, MDE.";
DWORD numberOfBytes = (DWORD)strlen(textToWrite);
Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
  • Thank you! Tried changing the encoding in VS, but it did not work. It might be my fault. However, the multiply way worked. – Sergio Calderon Feb 12 '23 at 22:26
  • 2
    If you write UTF-16 to a .txt file you should write a BOM at the start so other programs can identify the encoding. – Jonathan Potter Feb 12 '23 at 23:12
  • FYI, neither code example should compile, as neither `wcslen()` nor `strlen()` take `LPCVOID` as input. Just because `WriteFile()` takes `LPCVOID`doesn't mean your variables should be declared as `LPCVOID`. All pointer types are implicitly convertible to `LPCVOID`. Use proper types for variables, eg `LP(C)STR` aka `(const) char*` for narrow strings, and `LP(C)WSTR` aka `(const) wchar_t*` for wide strings. – Remy Lebeau Feb 13 '23 at 06:07
  • 2
    @RemyLebeau [C allows implicit conversion to/from void*](https://godbolt.org/z/T5n7Y5jq5). While I agree with you that one shouldn't use a `void*` in this code just because `WriteFile` does, I prefer to to limit my answers in scope with minimum changes to the OP code. – Yakov Galka Feb 13 '23 at 14:22
  • @YakovGalka whoops, my bad, I didn't see the [tag:c] tag, thought it was a [tag:c++] question. – Remy Lebeau Feb 13 '23 at 15:53