By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,672 Members | 1,628 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,672 IT Pros & Developers. It's quick & easy.

Formating a string using sprintf and showing it in MessageBox!

P: n/a
Hi everyone
I want to format a string (using sprintf) and put it in a messagebox
but however I try to do it, it doesn't seem to work.
Here is an example sample of what i try to do:

char msg[120];
string my_name = "John";

sprintf (msg, "My name is: %s ", my_name);
MessageBox(NULL, msg, NULL, MB_OK);
And this is the error I get:

error C2664: 'MessageBoxW' : cannot convert parameter 2 from 'char
[120]' to 'const unsigned short *'
Types pointed to are unrelated; conversion requires reinterpret_cast,
C-style cast or function-style cast

I know that MessageBox wants a LPCTSTR as its second parameter. If I
use that instead (see below)...

LPCTSTR msg;
string my_name = "John";

sprintf (msg, "My name is: %s ", my_name);
MessageBox(NULL, msg, NULL, MB_OK);
....I get the following error:

error C2664: 'sprintf' : cannot convert parameter 1 from 'const
unsigned short *' to 'char *'
Types pointed to are unrelated; conversion requires reinterpret_cast,
C-style cast or function-style cast

Seems like what ever I try to use either sprintf or MessageBox is not
happy. If I try to cast 'msg' in either sprintf or MessageBox I just
get junk as my output.
Does anyone have a suggestion how I can solve this? Please note that I
don't want to use CString since my platform does not seem to support
that. An example code of how I can solve this problem would be much
appreciated.

Thanks a lot for your help.
/Babak

Nov 17 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a
Hi babak!
I want to format a string (using sprintf) and put it in a messagebox
but however I try to do it, it doesn't seem to work.
Here is an example sample of what i try to do:

char msg[120];
string my_name = "John";

sprintf (msg, "My name is: %s ", my_name);
MessageBox(NULL, msg, NULL, MB_OK);
And this is the error I get:

error C2664: 'MessageBoxW' : cannot convert parameter 2 from 'char
[120]' to 'const unsigned short *'


You compile a UNICODE program but you heare are dealing with ANSI strings...

Change it to

<code>
ifdef _UNICODE
#define tstring std::wstring
#else
#define tstring std::string
#endif

TCHAR msg[120];
tstring my_name = _T("John");
__stprintf(msg, _T("My name is: %s "), (LPCTSTR) my_name);
MessageBox(NULL, msg, NULL, MB_OK);
</code>

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Nov 17 '05 #2

P: n/a
> error C2664: 'MessageBoxW' : cannot convert parameter 2 from 'char
[120]' to 'const unsigned short *'
Types pointed to are unrelated; conversion requires reinterpret_cast,
C-style cast or function-style cast Looks like the applicaiton is Unicode.
LPCTSTR msg;
string my_name = "John";

sprintf (msg, "My name is: %s ", my_name);
MessageBox(NULL, msg, NULL, MB_OK); What is "string" ?
Anyway, try:

TCHAR msg[120];
TCHAR *my_name = _T("John");

_stprintf (msg, _T("My name is: %s "), my_name);
MessageBox(NULL, msg, NULL, MB_OK);

Notes:
----------------
LPCTSTR msg;
will crash you application, because it is a non-initialized pointer.
It expands to
LPCTSTR:
LP = Long Pointer (the long is obsolete, from the old days when
Intel procesors used segmented memory)
C = const
T = generic text type
STR = string
So, this becomes:
if Non-Unicode: const char * msg;
if Unicode: const wchar_t * msg;
Generic: const TCHAR * msg;
----------------
Note _stprintf insted of sprintf and _T(".....")
If you read the doc for sprintf, you will see a table named
"Generic-Text Routine Mappings". "TCHAR.H routine" is what you
allways want.
----------------
Read about the the "Generic-Text Routine Mappings" in MSDN.
----------------
Read this blurb: http://www.mihainita.net/20050306b.shtml
Please note that I don't want to use CString since my platform does not
seem to support that.

CString is part of MFC (MFC/ATL in VC.NET). If you configure the
project to use MFC, then you will get it.

--
Mihai Nita [Microsoft MVP, Windows - SDK]
------------------------------------------
Replace _year_ with _ to get the real email
Nov 17 '05 #3

P: n/a
><code>
ifdef _UNICODE
#define tstring std::wstring
#else
#define tstring std::string
#endif

TCHAR msg[120];
tstring my_name = _T("John");
__stprintf(msg, _T("My name is: %s "), (LPCTSTR) my_name);
MessageBox(NULL, msg, NULL, MB_OK);
</code>

I did not think about std::string :-)
Jochen is right, that is what you should do.

But he is not right in double-underscore in __stprintf :-)
Correct that, and you have a running thing.

--
Mihai Nita [Microsoft MVP, Windows - SDK]
------------------------------------------
Replace _year_ with _ to get the real email
Nov 17 '05 #4

P: n/a
Hi Jochen
Thanks for your help. I tried what you suggested and got the following
error:

error C2440: 'type cast' : cannot convert from 'class
std::basic_string<unsigned short,struct std::char_traits<unsigned
short>,class std::allocator<unsigned short> >' to 'const unsigned short
*'
No user-defined-conversion operator available that can perform this
conversion, or the operator cannot be called

This doesn't seem like the right approach to me because to my
understanding the variable that the compiler is not happy with is 'msg'
(i.e the first parameter in sprintf and second parameter in MessageBox)
and not 'string' (which you refer to as 'tstring' in your code) that
you changed in your code. Have I missunderstood this totally?

/Babak

Nov 17 '05 #5

P: n/a
Hi Mihai!
__stprintf(msg, _T("My name is: %s "), (LPCTSTR) my_name);


But he is not right in double-underscore in __stprintf :-)
Correct that, and you have a running thing.


Upps... it was a copy-and-past error...

But to be even better, he should use "_sntprintf" instead of "_stprintf"!

<code>
ifdef _UNICODE
#define tstring std::wstring
#else
#define tstring std::string
#endif

TCHAR msg[120];
tstring my_name = _T("John");
_sntprintf(msg, 120, _T("My name is: %s "), (LPCTSTR) my_name);
MessageBox(NULL, msg, NULL, MB_OK);
</code>
--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Nov 17 '05 #6

P: n/a
Thanks for explanations in the notes to your first message, Mihai. It
is all now a little bit more clear to me. However, as I wrote in my
last message, this still does not seem to work (I used single
underscore in _sprintf). Any suggestions?

Thanks for your help.
/Babak

Nov 17 '05 #7

P: n/a
Hi babak!
error C2440: 'type cast' : cannot convert from 'class
std::basic_string<unsigned short,struct std::char_traits<unsigned
short>,class std::allocator<unsigned short> >' to 'const unsigned short
*'
No user-defined-conversion operator available that can perform this
conversion, or the operator cannot be called


Upps.. I forgot that the STL-(w)string class has not const-operator...

Here is a complete working example:

#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#pragma comment(lib, "user32.lib")

#include <string>

#ifdef _UNICODE
#define tstring std::wstring
#else
#define tstring std::string
#endif

int _tmain()
{
TCHAR msg[120];
tstring my_name = _T("John");
_sntprintf(msg, 120, _T("My name is: %s "), my_name.c_str());
MessageBox(NULL, msg, NULL, MB_OK);
}

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Nov 17 '05 #8

P: n/a
Here is a complete working example:

Again a really, really complete working example:

#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#pragma comment(lib, "user32.lib")

#include <string>

#ifdef _UNICODE
#define tstring std::wstring
#else
#define tstring std::string
#endif

int _tmain()
{
TCHAR msg[120+1];
tstring my_name = _T("John");
_sntprintf(msg, 120, _T("My name is: %s "), my_name.c_str());
msg[120] = 0;
MessageBox(NULL, msg, NULL, MB_OK);
}

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Nov 17 '05 #9

P: n/a
Thanks a lot for your help. Not it seems to be working properly!

/Babak

Mihai N. skrev:
error C2664: 'MessageBoxW' : cannot convert parameter 2 from 'char
[120]' to 'const unsigned short *'
Types pointed to are unrelated; conversion requires reinterpret_cast,
C-style cast or function-style cast

Looks like the applicaiton is Unicode.
LPCTSTR msg;
string my_name = "John";

sprintf (msg, "My name is: %s ", my_name);
MessageBox(NULL, msg, NULL, MB_OK);

What is "string" ?
Anyway, try:

TCHAR msg[120];
TCHAR *my_name = _T("John");

_stprintf (msg, _T("My name is: %s "), my_name);
MessageBox(NULL, msg, NULL, MB_OK);

Notes:
----------------
LPCTSTR msg;
will crash you application, because it is a non-initialized pointer.
It expands to
LPCTSTR:
LP = Long Pointer (the long is obsolete, from the old days when
Intel procesors used segmented memory)
C = const
T = generic text type
STR = string
So, this becomes:
if Non-Unicode: const char * msg;
if Unicode: const wchar_t * msg;
Generic: const TCHAR * msg;
----------------
Note _stprintf insted of sprintf and _T(".....")
If you read the doc for sprintf, you will see a table named
"Generic-Text Routine Mappings". "TCHAR.H routine" is what you
allways want.
----------------
Read about the the "Generic-Text Routine Mappings" in MSDN.
----------------
Read this blurb: http://www.mihainita.net/20050306b.shtml
Please note that I don't want to use CString since my platform does not
seem to support that.

CString is part of MFC (MFC/ATL in VC.NET). If you configure the
project to use MFC, then you will get it.

--
Mihai Nita [Microsoft MVP, Windows - SDK]
------------------------------------------
Replace _year_ with _ to get the real email


Nov 17 '05 #10

P: n/a
> But to be even better, he should use "_sntprintf" instead of "_stprintf"!
....
TCHAR msg[120];
tstring my_name = _T("John");
_sntprintf(msg, 120, _T("My name is: %s "), (LPCTSTR) my_name);


True. What I normaly do is this:

#define DIM(a) (sizeof(a)/sizeof(a[0]))
_sntprintf( msg, DIM(msg), ... );

This way you don't have to manualy keep in sync the
_sntprintf parameter with the buffer size.
You just have to be careful to use it only on pointers,
not on arrays.
I also have something in C++, using templates, that gives
compile error if used on pointers.
But is a bit long to post here. And VC2005 will have something anyway :-)

--
Mihai Nita [Microsoft MVP, Windows - SDK]
------------------------------------------
Replace _year_ with _ to get the real email
Nov 17 '05 #11

P: n/a
Hi Mihai!
But to be even better, he should use "_sntprintf" instead of "_stprintf"!

TCHAR msg[120];
tstring my_name = _T("John");
_sntprintf(msg, 120, _T("My name is: %s "), (LPCTSTR) my_name);


True. What I normaly do is this:

#define DIM(a) (sizeof(a)/sizeof(a[0]))
_sntprintf( msg, DIM(msg), ... );


But this is wrong... (as I also did in my first most... ;-) )

If the resulting string is exactly the size of the passed buffer, then
*no* NUl characater will be appended...

So you need to do:
#define DIM(a) (sizeof(a)/sizeof(a[0]))
_snprintf(msg, DIM(msg)-1, ...);
msg[DIM(msg)-1] = 0;

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
Nov 17 '05 #12

P: n/a
> So you need to do:
#define DIM(a) (sizeof(a)/sizeof(a[0]))
_snprintf(msg, DIM(msg)-1, ...);
msg[DIM(msg)-1] = 0;


In fact, if you do msg[DIM(msg)-1] = 0;
you can do _snprintf(msg, DIM(msg), ...); without problem.
It is just about "what's your style."

Ok, now we move from internationalization to security.
I know, snprintf is unsafe. You should use the safe string API from MS.

But I kust did not feel like taking any piece of code from newsgroups and
rising it to production code level.
This is what I do with my production code, true.
But on newsgroups, sometimes I do feel like baby-sitting, sometimes not.

For instance, I would not start here a discution about portability.
Not today. Some other day, maybe :-)

--
Mihai Nita [Microsoft MVP, Windows - SDK]
------------------------------------------
Replace _year_ with _ to get the real email
Nov 17 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.