Solved

Unicode/STL/Varargs problem

Posted on 2001-08-06
7
1,588 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
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
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 

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

NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

Question has a verified solution.

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

Suggested Solutions

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: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
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.
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

809 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