Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. WideCharToMultiByte

WideCharToMultiByte

Scheduled Pinned Locked Moved C / C++ / MFC
questionvisual-studio
2 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    kasturirawat
    wrote on last edited by
    #1

    Following code gives assertion fail under VS 7 (sometime with 6) void StringFromWide(const wchar_t* pwch, int cch, char *psz, int szLen) { if(cch == 0) { cch = wcslen(pwch); // TODO it will display only first four char } if(cch > szLen) cch = szLen; WideCharToMultiByte(CP_ACP, 0, pwch, cch, psz, cch, NULL, NULL); psz[cch] = '\0'; } As workaround I'm using following code void StringFromWide(const wchar_t* pwch, int cch, char *psz, int szLen) { size_t szt; if(cch == 0) { szt = wcslen(pwch); cch = sizeof(szt) ;// but this will retrieve four chars only } if(cch > szLen) cch = szLen; WideCharToMultiByte(CP_ACP, 0, pwch, cch, psz, cch, NULL, NULL); psz[cch] = '\0'; } What is missing here?

    P 1 Reply Last reply
    0
    • K kasturirawat

      Following code gives assertion fail under VS 7 (sometime with 6) void StringFromWide(const wchar_t* pwch, int cch, char *psz, int szLen) { if(cch == 0) { cch = wcslen(pwch); // TODO it will display only first four char } if(cch > szLen) cch = szLen; WideCharToMultiByte(CP_ACP, 0, pwch, cch, psz, cch, NULL, NULL); psz[cch] = '\0'; } As workaround I'm using following code void StringFromWide(const wchar_t* pwch, int cch, char *psz, int szLen) { size_t szt; if(cch == 0) { szt = wcslen(pwch); cch = sizeof(szt) ;// but this will retrieve four chars only } if(cch > szLen) cch = szLen; WideCharToMultiByte(CP_ACP, 0, pwch, cch, psz, cch, NULL, NULL); psz[cch] = '\0'; } What is missing here?

      P Offline
      P Offline
      Philippe Mori
      wrote on last edited by
      #2

      I assume that valid null terminated strings are passed to the functions and that cch is the length (not including the ending NULL) of the original string (0 means compute) and szLen is the buffer size of the output including the room for the NULL terminator. In such case, then if cch is greater or equal to szLen, psz[cch] will write one character after the end of the buffer (it should be psz[cch-1]). Also the alternate code is wrong. The reason why it will often works is because szLen is greater that 4 in your case. Doing a sizeof on the returned size return the size of a variable of type size_t (which is probably an unsigned int or an unsigned long) and not the value hold in the variable. Note that you uses assertion in your code to validate what you are doing. For ex. adding ASSERT(strlen(psz) < szLen) would have typically catch the error after the memory is overwritten but before the application crash so it would then be easy to apply the fix! You should also check the result of the call to WideCharToMultiByte. If it fails (and it can), the output will contains garbage (if it wasn't initialized externally). Also if output is really multibyte, then some UNICODE characters may be converted to 2 multibyte characters and it that case, the code would be incorrect. Finally, it may be easier (and less error-prone) to uses macros like W2A (or classes like _bstr_t, CString, CComBSTR,...) to make conversions if you do not needs the extra functionality accessible only from the API. In a few words: length and size are different... Knows what you are doing. Also, you may allocate a bit more memory than necessary to be on the safe side. Philippe Mori

      1 Reply Last reply
      0
      Reply
      • Reply as topic
      Log in to reply
      • Oldest to Newest
      • Newest to Oldest
      • Most Votes


      • Login

      • Don't have an account? Register

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • World
      • Users
      • Groups