Unicode/STL/Varargs problem

Posted on 2001-08-06
Last Modified: 2013-11-20
Hi.  I am very stumped by this problem.
I have a small Unicode MFC project (_UNICODE is defined).
VC 6.0 / Win2K .  Also it uses STL strings.

Building the code below works ok.
But uncommenting the line in test_msgs() causes
incorrect strings to pop up in the dialog.
And if the function is called a 2nd time, the app crashes.

Any ideas?  Thank you very much.

#include <stdarg.h>
#include <string>

typedef unsigned short unichar;

class ustring : public std::basic_string<unichar>
     ustring() {}
     ustring(const unichar *rhs) : std::basic_string<unichar>(rhs) {}
     ustring(const ustring &rhs) : std::basic_string<unichar>(rhs) {}

static void popup_msg(const ustring &msg, ...) {
     wchar_t buf[2048];

     va_list args;
     va_start(args, msg);
     vswprintf(buf, msg.c_str(), args);


void test_msgs(void) {
     wchar_t wbuf[80];

     lstrcpy(wbuf,L"WChar test: %s");
     CString cstr="test 10";

     // When I uncomment the following line, it breaks
     //ustring ustr1=L"test 11";

     ustring ustr2(wbuf);
Question by:bwilhelm
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions

Expert Comment

ID: 6357218
there are MS definition for UNICODE STL strings its called wstring (so you can get read of ustring)

Expert Comment

ID: 6358555
first, if you use unicode you should define both the symbol _UNICODE and UNICODE ; some of the microsoft-code is not being changed to _UNICODE yet.

the line: CString cstr="test 10";
should look like this:

  CString cstr= L"test 10";  //or
  CString cstr= _T("test 10");

there are also wrapper-classes to handle wchar_t, for.ex _bstr_t, f.ex.:
_bstr_t bstrBuf( L"test 10");
there are several assign-operators you can use to transform char to wchar_t.

instead of lstrcpy() you should use _tcscpy() or wcscpy(), because lstrcpy() is not for unicode use.

Expert Comment

ID: 6365469

The problem here in:

// When I uncomment the following line, it breaks
//ustring ustr1=L"test 11";

is ustri is a class, you need constructor to create an instence.
The parameter should be  unichar -- unsigned short int, wchar_t

You can do:

wchar_t  asc[8]= {0x74,0x65,0x73,0x74,0x20,0x31,0x31,NULL};  //alloc and init
ustring ustr1(asc);   // construct
popup_msg(ustr1,cstr);  // display

You will get right display.

The values in init are:
char       unicode       ascii
t               0x0074        0x74
e             0x0065        0x65
s             0x0073        0x73
space    0x0020        0x20
1             0x0031        0x31
NULL -- unicode string end.

Ji Zhang
Database Solutions Engineer FAQs

In this series, we will discuss common questions received as a database Solutions Engineer at Percona. In this role, we speak with a wide array of MySQL and MongoDB users responsible for both extremely large and complex environments to smaller single-server environments.


Author Comment

ID: 6369160
Thanks for your tips.
I tried them all and still have the same problem.

Here's the latest, pared down a little lot.
Do you have any other suggestions?  Thanks a lot. - Bruce

#include <stdarg.h>
#include <string>

typedef std::basic_string<wchar_t> unistr;

#define DISPLAY_STR(str)          AfxMessageBox(CString(str),MB_OK)

// this function works
static void popup_msg1(const unistr &msg, wchar_t *wptr) {
    wchar_t buf[2048];



// this function does not work
static void popup_msg2(const unistr &msg, ...) {
    wchar_t buf[2048];

    va_list args;
    // the following line crashes


void test_msgs2(void) {
    wchar_t wbuf[80], wbuf2[80];
    wcscpy(wbuf,_T("WChar Test: %s"));
    wcscpy(wbuf2,_T("test 12"));

    unistr ustr(wbuf);
    popup_msg1(ustr,wbuf2);     // this call succeeds
    popup_msg2(ustr,wbuf2);     // this call crashes

Accepted Solution

ShaunWilde earned 300 total points
ID: 6371568
ahhh - sorry I should have looked more closely - this is a known problem with using references and the va_* macros see

you can use their fix or you could just change your code

static void popup_msg2(const unistr *msg, ...) {
   wchar_t buf[2048];

   va_list args;
   // the following line crashes




Author Comment

ID: 6372494
Thanks, that is exactly the problem I was seeing.

Expert Comment

ID: 6372915
glad to help - I learnt something from this also

Featured Post

 Database Backup and Recovery Best Practices

Join Percona’s, Architect, Manjot Singh as he presents Database Backup and Recovery Best Practices (with a Focus on MySQL) on Thursday, July 27, 2017 at 11:00 am PDT / 2:00 pm EDT (UTC-7). In the case of a failure, do you know how long it will take to restore your database?

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …

617 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question