Re: _stprintf
- From: Joseph M. Newcomer <newcomer@xxxxxxxxxxxx>
- Date: Tue, 01 Aug 2006 10:53:16 -0400
The documentation for StringCchPrintf talks about counts of characters. In the ANSI
compilation, each character occupies exactly one TCHAR. I'm not sure how you figure a
character can occupy two TCHARs (which are just chars in ANSI) since each char has a value
of exactly the range 0..255, which fits in exactly one char.
The documentation for StringCchPrintf says
============================================
StringCchPrintf Function
StringCchPrintf is a replacement for sprintf. It accepts a format string and a list of
arguments and returns a formatted string. The size, in characters, of the destination
buffer is provided to the function to ensure that StringCchPrintf does not write past the
end of this buffer.
Syntax
HRESULT StringCchPrintf(
LPTSTR pszDest,
size_t cchDest,
LPCTSTR pszFormat,
...
);
Parameters
pszDest
[out] Pointer to a buffer which receives the formatted, null-terminated string created
from pszFormat and its arguments.
cchDest
[in] Size of the destination buffer, in ****characters****. This value must be
sufficiently large to accommodate the final formatted string plus 1 to
account for the terminating null character. The maximum number of
characters allowed is STRSAFE_MAX_CCH.
pszFormat
[in] Pointer to a buffer containing a printf-style format string. This string must be
null-terminated.
....
[in] Arguments to be inserted into pszFormat.
=====================================
Note that the word ****characters**** is clearly in italics in the original documentation.
Now where, in the above documentation, does it say that a 'character' is exactly one byte?
How do you infer that a 'character', in ANSI mode, can occupy two bytes? Where is there
the slightest confusion between the char and wchar_t data type here? I think you have a
very serious confusion in understanding the difference between the terms 'character'
(which is one or two bytes depending on the compilation mode), 'char' (which is always one
byte), 'wchar_t' (which is always two bytes), and TCHAR (which is one or two bytes
depending on the compilation mode).
I have no idea what you mean by "one 2-TCHAR character". This is a contradiction. A
character is by definition a 1-TCHAR character, because that is what is meant by
"character". A TCHAR[2] holds two characters. A string is a sequence of zero or more
characters followed by a NUL character. In ANSI mode, this means for a TCHAR[2] to
represent a string, it holds a single 8-bit character and a single 8-bit NUL character, in
Unicode this means it holds a single 2-byte Unicode character and 2-byte NUL character.
How can you get a 2-byte "character" in ANSI mode? This contradicts the whole concept of
"character" as specified for each mode. (Note that in ANSI mode, you can have UTF
encoding that represents a single 8-bit character as two characters, but note that this is
two characters, and in ANSI mode that is two bytes. But StringCchPrintf is not going to
somehow magically convert anything to UTF-8 in the process of formatting it. Since the
target formatting string, %c, formats exactly one character, a 2-character buffer, in any
mode, will suffice, and StringCchPrintf will work. UTF-8 is a multibyte encoding and that
is a discussion completely separate from the one we are having here).
joe
On Tue, 1 Aug 2006 10:27:37 +0900, "Norman Diamond" <ndiamond@xxxxxxxxxxxxxxxx> wrote:
The documentation for StringCchPrintf talks about counts of characters. InJoseph M. Newcomer [MVP]
an ANSI compilation each character occupies one or two TCHARs depending on
the actual character. The documentation for StringCchPrintf doesn't say
that TCHARs are counted where it does say that characters are counted.
Dr. Newcomer, you KNOW how, in an ANSI compilation, one 2-TCHAR character
will overflow a buffer which has enough space for only one 1-TCHAR
character.
"Joseph M. Newcomer" <newcomer@xxxxxxxxxxxx> wrote in message
news:tppsc21810onsurc601ligkkiivh5pui77@xxxxxxxxxx
The libraries are shared and there is already a copy of them loaded.
What is wrong with StringCchPrintf? It won't overflow the buffer, which
is a good thing.
The char/wchar_t is what TCHAR means. But it is signed, which implies
sign extension for
any Unicode character > 7FFFU. This will not produce a good result in
most cases. WORD
will handle a char value because it won't sign extended.
I made B an array of two characters. not two bytes. I distinctly recall
writing
TCHAR B[2];
which is two characters. This means in Unicode it is 4 bytes.
StringCchPrintf will format the string, which is one character plus a
terminal null
character. Do not confuse "character" with "byte". StringCchPrintf will
copy the single
character and add a NULL character, which the last I looked, was two
characters, the size
of the array.
joe
On Mon, 31 Jul 2006 19:40:24 +0900, "Norman Diamond"
<ndiamond@xxxxxxxxxxxxxxxx> wrote:
"Joseph M. Newcomer" <newcomer@xxxxxxxxxxxx> wrote in messageJoseph M. Newcomer [MVP]
news:e57oc2lrr2nd1j0nt83h8e7h02ahjsbqih@xxxxxxxxxx
Use CString::Format as the preferred choice.
On "real" Windows I agree. On Windows CE where extra libraries will
occupy
the machine's RAM, it might not be a good idea.
If you MUST use some form like _stprintf, use StringCchPrintf (I think
that's the name, but search for strsafe.h on the MSDN) which at least
will
avoid any possibility of buffer overflow
As documented it will not have such a beneficial effect.
StringCchPrintf(_T("%c"), B, sizeof(B) / sizeof(TCHAR), (BYTE)('a' +
i));
Mihai N. addressed a problem with your cast to BYTE and you made an
adjustment which I'm still thinking about. Since arguments to
StringCchPrintf are either Unicode or ANSI, the last argument should be
either char or wchar_t, and I'm trying to figure out if WORD is guaranteed
to marshall a char value properly.
More importantly is that, as documented, buffer overflow can very easily
occur. Suppose we have an ANSI compilation and make B an array of 2
chars.
Then the buffer has enough space for 1 single-byte character plus a null
character. But if the last argument is a double-byte character then
StringCchPrintf is documented to copy both bytes plus a single-byte null
character, total 3 bytes.
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- References:
- Re: _stprintf
- From: Joseph M . Newcomer
- Re: _stprintf
- From: Norman Diamond
- Re: _stprintf
- From: Joseph M . Newcomer
- Re: _stprintf
- From: Norman Diamond
- Re: _stprintf
- Prev by Date: Re: Adding text to a listbox from main frame
- Next by Date: Re: ANSI string from UNICODE app.
- Previous by thread: Re: _stprintf
- Next by thread: Re: _stprintf
- Index(es):
Relevant Pages
|