Solved

Unicode/STL/Varargs problem

Posted on 2001-08-06
7
1,592 Views
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>
{
public:
     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);
     va_end(args);

     AfxMessageBox(CString(buf),MB_OK);
}

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);
     popup_msg(ustr2,cstr);
}
0
Comment
Question by:bwilhelm
[X]
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
7 Comments
 
LVL 9

Expert Comment

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

Expert Comment

by:missionImpossible
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.
0
 
LVL 1

Expert Comment

by:jizhang
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
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:bwilhelm
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];

    swprintf(buf,msg.c_str(),wptr);

    DISPLAY_STR(buf);
}

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

    va_list args;
    va_start(args,msg);
    // the following line crashes
    vswprintf(buf,msg.c_str(),args);
    va_end(args);

    DISPLAY_STR(buf);
}

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
}
0
 
LVL 9

Accepted Solution

by:
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

http://support.microsoft.com/support/kb/articles/Q119/3/94.asp

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;
   va_start(args,msg);
   // the following line crashes
   vswprintf(buf,msg->c_str(),args);
   va_end(args);

   DISPLAY_STR(buf);
}

...

popup_msg2(&ustr,wbuf2);  
0
 

Author Comment

by:bwilhelm
ID: 6372494
Thanks, that is exactly the problem I was seeing.
0
 
LVL 9

Expert Comment

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

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Unix / Linux grid computing 5 171
Replacement selected text 2 69
Whole sheet autoscrub still needed 19 54
Smart Camera scanning and reading information 3 126
In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
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.
How to Install VMware Tools in Red Hat Enterprise Linux 6.4 (RHEL 6.4) Step-by-Step Tutorial

734 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