Discussion:
Unicode data types
(too old to reply)
Z.K.
2008-04-20 21:09:04 UTC
Permalink
I was trying to convert the sprintf statement to sprintf_s, but though
it compiles, it gives me an exception everytime when it reaches the
sprintf_s statement and I am not really sure why. My knowledge of
unicode and these new functions in VS 2005 are still new to me though I
thought this would work since the only difference was a size requirement.


const int BUFFSIZE = 128;

char buffer2[BUFFSIZE];

lpstrEditcmd = &buffer2[0];

//sprintf(lpstrEditcmd,"%s\\edit.com",lpstrSysDir);
sprintf_s(lpstrEditcmd,sizeof(lpstrEditcmd),"%s\\edit.com",lpstrSysDir);


Of course if I just arbitrarily put in a size such as 128, then it gets
passed that statement. I have used this same code in Visual 2003
without the modifications and it worked fine.


Z.K.
Giovanni Dicanio
2008-04-20 21:37:23 UTC
Permalink
I was trying to convert the sprintf statement to sprintf_s, but though it
compiles, it gives me an exception everytime when it reaches the sprintf_s
statement and I am not really sure why.
Could you please be more specific about the "exception"?
Is it a C++ run-time exception? Or it is a compile-time error?
My knowledge of unicode and these new functions in VS 2005 are still new
to me though I thought this would work since the only difference was a
size requirement.
const int BUFFSIZE = 128;
char buffer2[BUFFSIZE];
To code Unicode aware, you should use TCHAR and not char:

TCHAR buffer2[ BUFFSIZE ];

Now BUFFSIZE is the count of TCHAR's, which translates to the count of
char's (bytes) in ANSI/MBCS builds, or to the count of wchar_t's (2 bytes
per wchar_t) in Unicode builds.
lpstrEditcmd = &buffer2[0];
lpstrEditcmd should be TCHAR*.
//sprintf(lpstrEditcmd,"%s\\edit.com",lpstrSysDir);
sprintf_s(lpstrEditcmd,sizeof(lpstrEditcmd),"%s\\edit.com",lpstrSysDir);
You should use _stprintf_s, which is the Unicode-aware version of sprintf_s.

http://msdn2.microsoft.com/en-us/library/ce3zzk1k(VS.80).aspx

Moreover, please pay attention to 2nd parameter of _stprintf_s:
you need the size of the buffer (in TCHAR) as 2nd parameter, but if
lpstrEditcmd is a TCHAR* (i.e.: just a pointer), your code
sizeof(lpstrEditcmd) is just a size of a *pointer* (= 4 bytes on 32 bits
architectures).

If you want to write something to a buffer - call it 'Dest' - being Unicode
aware, you should use something like this:

<code>

// Destination string buffer (statically defined on the stack)
TCHAR Dest[ 500 ];

// Format string to that buffer (Unicode aware)
_stprintf_s(
Dest, // Destination buffer
_countof( Dest ), // Count of TCHAR's in buffer
_T("%s\\edit.com"), // Format string
lpstrSysDir // I assume it is a TCHAR*
);

</code>

There are also functions like StringCbPrintf or StringCchPrintf for that
purpose.

StringCbPrintf:
http://msdn2.microsoft.com/en-us/library/ms647510(VS.85).aspx

StringCchPrintf:
http://msdn2.microsoft.com/en-us/library/ms647541(VS.85).aspx

However, IMHO the best thing to do is to use a robust string class, like
CString.
CString defines operators like + and +=, that help in concatenating strings.
And there is also the CString::Format method for printf-like formatting.

I prefer using robust string classes instead of programming using raw
C-style arrays of TCHARs...
Of course if I just arbitrarily put in a size such as 128, then it gets
passed that statement. I have used this same code in Visual 2003 without
the modifications and it worked fine.
Maybe in VS2003 the default compilation model was MBCS/ANSI, but in
VS2005/2008 the default model is Unicode, so you are running into problems
due to this new default character model.
If you program Unicode-aware, using TCHAR's, etc. you should have no
problems.

HTH,
Giovanni
Norman Bullen
2008-04-20 21:55:34 UTC
Permalink
Post by Z.K.
I was trying to convert the sprintf statement to sprintf_s, but though
it compiles, it gives me an exception everytime when it reaches the
sprintf_s statement and I am not really sure why. My knowledge of
unicode and these new functions in VS 2005 are still new to me though I
thought this would work since the only difference was a size requirement.
const int BUFFSIZE = 128;
char buffer2[BUFFSIZE];
lpstrEditcmd = &buffer2[0];
//sprintf(lpstrEditcmd,"%s\\edit.com",lpstrSysDir);
sprintf_s(lpstrEditcmd,sizeof(lpstrEditcmd),"%s\\edit.com",lpstrSysDir);
Of course if I just arbitrarily put in a size such as 128, then it gets
passed that statement. I have used this same code in Visual 2003
without the modifications and it worked fine.
Z.K.
Your problem is that you're passing the size of a pointer instead of the
size of the buffer.

I would remove the pointer entirely and rewrite the statement as
sprintf_s(buffer2, sizeof buffer2, "%s\\edit.com", ... );

If you may need to upgrade this code to Unicode in the future, use
#include <TCHAR.H>
const int BUFFSIZE = 128;
TCHAR buffer2[BUFFSIZE];
_stprintf_s(buffer2, _countof(buffer2), _T("s\\edit.com"), ... (;
--
Norm

To reply, change domain to an adult feline.
David Wilkinson
2008-04-20 21:42:06 UTC
Permalink
Post by Z.K.
I was trying to convert the sprintf statement to sprintf_s, but though
it compiles, it gives me an exception everytime when it reaches the
sprintf_s statement and I am not really sure why. My knowledge of
unicode and these new functions in VS 2005 are still new to me though I
thought this would work since the only difference was a size requirement.
const int BUFFSIZE = 128;
char buffer2[BUFFSIZE];
lpstrEditcmd = &buffer2[0];
//sprintf(lpstrEditcmd,"%s\\edit.com",lpstrSysDir);
sprintf_s(lpstrEditcmd,sizeof(lpstrEditcmd),"%s\\edit.com",lpstrSysDir);
Of course if I just arbitrarily put in a size such as 128, then it gets
passed that statement. I have used this same code in Visual 2003
without the modifications and it worked fine.
Z.K.

Your question has nothing to do with Unicode (for Unicode strings you would use
swprintf_s).

You do not give the type of lpstrEditcmd, but its size is likely the size of a
pointer (4 or 8 bytes). But why do you need it?

Why don't you just do

const int BUFFSIZE = 128;
char buffer2[BUFFSIZE];
sprintf_s(buffer2, BUFFSIZE, "%s\\edit.com",lpstrSysDir);

?
--
David Wilkinson
Visual C++ MVP
Z.K.
2008-04-20 23:29:27 UTC
Permalink
Post by Z.K.
I was trying to convert the sprintf statement to sprintf_s, but though
it compiles, it gives me an exception everytime when it reaches the
sprintf_s statement and I am not really sure why. My knowledge of
unicode and these new functions in VS 2005 are still new to me though I
thought this would work since the only difference was a size requirement.
const int BUFFSIZE = 128;
char buffer2[BUFFSIZE];
lpstrEditcmd = &buffer2[0];
//sprintf(lpstrEditcmd,"%s\\edit.com",lpstrSysDir);
sprintf_s(lpstrEditcmd,sizeof(lpstrEditcmd),"%s\\edit.com",lpstrSysDir);
Of course if I just arbitrarily put in a size such as 128, then it gets
passed that statement. I have used this same code in Visual 2003
without the modifications and it worked fine.
Z.K.
Okay, thanks a lot everyone; you've answered several questions that I
had. I will give it another try.

Z.K.
Anders Karlsson
2008-04-23 10:16:29 UTC
Permalink
Post by Z.K.
Okay, thanks a lot everyone; you've answered several questions that I
had. I will give it another try.
Z.K.
there is a pretty good article about Unicode also here if you are new
to that too.

http://www.joelonsoftware.com/articles/Unicode.html

hth
Anders.
--
A: People bitching about top-posting
Post by Z.K.
Q: What's the most annoying thing on USENET?
Continue reading on narkive:
Loading...