__int64 to CString returns wrong values – C++ MFC

  • A+
Category:Languages

I want to convert a __int64 variable into a CString. The code is exactly this

__int64 i64TotalGB; CString totalSpace; i64TotalGB = 150; printf("disk space: %I64d GB/n", i64TotalGB); totalSpace.Format(_T("%I64d", i64TotalGB)); printf("totalSpace contains: %s", totalSpace); 

the first printf prints

"disk space: 150GB" 

which it's correct, but the second printf prints randomly high numbers like

"totalSpace contains: 298070026817519929"

I also tried to use a INT64 variable instead of a __int64 variable, but the result is the same. What can be the cause of this?

 


Here:

totalSpace.Format(_T("%I64d", i64TotalGB)); 

you're passing i64TotalGB as an argument to the _T() macro instead of passing it as the second argument to Format().

Try this:

totalSpace.Format(_T("%I64d"), i64TotalGB); 

Having said that, thanks to MS's mess (ha) around character encodings, using _T here is not the right thing, as CString is composed of a TCHAR and not _TCHAR. So taking that into account, might as well use TEXT() instead of T(), as it is dependent on UNICODE and not _UNICODE:

totalSpace.Format(TEXT("%I64d"), i64TotalGB); 

In addition, this line is wrong as it tries to pass an ATL CString as a char* or C-style string:

printf("totalSpace contains: %s", totalSpace); 

For which the compiler gives this warning:

warning C4477: 'printf' : format string '%s' requires an argument of type 'char *', but variadic argument 1 has type 'ATL::CString' 

While the structure of CString is practically compatible with passing it like you have, this is still formally undefined behavior. Use CString::GetString() to safeguard against it:

printf("totalSpace contains: %ls", totalSpace.GetString()); 

Note the %ls as under my configuration totalSpace.GetString() returned a const wchar_t*.


Having said ALL that, here's a general advice, regardless of the direct problem behind the question. The far better practice nowadays is slightly different altogether, and I quote from the respectable answer by @IInspectable, saying that "generic-text mappings were relevant 2 decades ago".

What's the alternative? In the absence of good enough reason, try sticking explicitly to CStringW (A Unicode character type string with CRT support). Prefer the L character literal over the archaic data/text mappings that depend on whether the constant _UNICODE or _MBCS has been defined in your program. Conversely, the better practice would be using the wide-character versions of all API and language library calls, such as wprintf() instead of printf().

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: