Solved

Unicode/STL/Varargs problem

Posted on 2001-08-06
7
1,585 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
Comment Utility
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
Comment Utility
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
Comment Utility

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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:bwilhelm
Comment Utility
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
Comment Utility
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
Comment Utility
Thanks, that is exactly the problem I was seeing.
0
 
LVL 9

Expert Comment

by:ShaunWilde
Comment Utility
glad to help - I learnt something from this also
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Windows Drag & Drop Location 2 85
deburging in oracle form 12 76
NotAlone Challenge 20 70
MaxSpan challenge 9 65
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 …
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.
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

762 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

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now