How to throw exception in VIsual C++ using a wchar_t string? - visual-c++

I have legacy code which I am incrementally porting to Unicode characters in Visual C++ (wchar_t). I've encountered this bit of code that I'd like to convert:
char tmp[256];
sprintf(tmp, "stuff");
throw exception(tmp);
I want to change it to something like this (this gives me a compile error on exception):
wchar_t tmp[256];
swprintf(tmp, "stuff");
throw exception(tmp);
So far I haven't found any document to give me the Unicode equivalent for throw exception, can anyone help me?
Of course I could convert my "tmp" back into a char string, but that just seems silly to have to do that.

std::exception does not support wchar_t strings, so you will have to either convert your wchar_t buffer into a separate char buffer, or do not switch to a wchar_t buffer to begin with as sprintf() does support formatting Unicode input via its %S and %ls formatting specifiers, eg:
char tmp[256];
sprintf(tmp, "%ls", wchar_t data here);
throw exception(tmp);

Related

Visual C++ run times error

All case run in Visual C++ 2005 environment
Function definition:
char *PQgetvalue(const PGresult *res, int tup_num, int field_num);
Case 1.
CString dd;
dd=(LPCTSTR) PQgetvalue(res,i,0);
when above is compiled with NO ERROR but dd has store garbage data like: 〱〰71〱1 몭몭몭몭몭몭ꮫꮫꮫꮫ
Case 2.
CString dd;
dd= PQgetvalue(res,i,0);
No Compilation error and provide correct output.
Question: How to convert Char* to CString
Case 3.
CString dd;
dd= PQgetvalue(res,i,0);
CString dd = PQgetvalue(res,i,0);
There is NO Difference between above code. But second case generate compilation error like:
error C2440: 'initializing' :
cannot convert from 'char *' to 'ATL::CStringT<BaseType,StringTraits>'
Please clarify anyone
For the first case. I guess you compile your project with Unicode character set (to verify open project settings dialog "Configuration properties" - "General" - "Character set"). Thus converting char* to const wchar_t* would gives you garbage. I.e. TCHAR is wchar_t when you compile with Unicode.
On the C2440. Please clarify whether code in Case 3 is correct (i.e. you supply all 3 lines to compiler as provided here.). Also I'd suggest you to search MSDN on this error.

How to convert BSTR string to Unsigned Char (Using com technology in the appln)

I am writing small application which uses com technology. I want to convert BSTR string to an unsigned char. To do this, i used W2A() Macro to convert from BSTR to String and then copied String.C_STR() to an unsigned char array. The code snippet is as follows:
Send(BSTR *packet, int length)
{
std::string strPacket = W2A(*packet);
unsigned char * pBuffer = new unsigned char [strPacket.length()+1];
memset(pBuffer,0,strPacket.length()+1);
memcpy(pBuffer,strPacket.c_str(),strPacket.length()+1);
}
This works fine when packet contains normal string. But if the packet contains a NUL character in it, the problem occurs. Some unknown characters appear after that NUL in the pBuffer i.e, after conversion.
Can anyone please let me know how to avoid that? Or is there any other way to do it correctly?
A BSTR is a Windows API type and must be managed with API macros or functions. If you cannot use W2A macro because your string may have null chars inside, you will have to use functions as WideCharToMultiByte that can convert from wide characters of BSTR to narrow chararacters for a char*. Be sure to have the SDK documentation. Alternatively, you could make you program use WCHARs

Unicode to char* c++ 11

I want to know if is there any way to convert a unicode code to a string or char in C++ 11.
I've been trying with extended latin unicode letter Á (as an example) which has this codification:
letter: Á
Unicode: 0x00C1
UTF8 literal: \xc3\x81
I've been able to do so if it's hardcoded as:
const char* c = u8"\u00C1";
But if i got the byte sequence as a short, how can I do the equivalent to get the char* or std::string 'Á'?
EDIT, SOLUTION:
I was finally able to do so, here is the solution if anyone needs it:
std::wstring ws;
for(short input : inputList)
{
wchar_t wc(input);
ws += wc;
}
std::wstring_convert<std::codecvt_utf8<wchar_t>> cv;
str = cv.to_bytes(ws);
Thanks for the comments they were very helpful.
The C++11 standard contains codecvt_utf8, which converts between some internal character type (try char16_t if your compiler has it, otherwise wchar_t) and UTF-8 encoding.
The problems is that char is only one byte length, while unicode characters require a size of two bytes.
You can still treat it as char*, but you must remember that you are not dealing with an ascii string (there will be zeros).
You may have to switch to wchar_t.

Converting wchar_t* to char* on iOS

I'm attempting to convert a wchar_t* to a char*. Here's my code:
size_t result = wcstombs(returned, str, length + 1);
if (result == (size_t)-1) {
int error = errno;
}
It indeed fails, and error is filled with 92 (ENOPROTOOPT) - Protocol not available.
I've even tried setting the locale:
setlocale(LC_ALL, "C");
And this one too:
setlocale(LC_ALL, "");
I'm tempted to just throw the characters with static casts!
Seems the issue was that the source string was encoded with a non-standard encoding (two ASCII characters for each wide character), which looked fine in the debugger, but clearly internally was sour. The error code produced is clearly not documented, but it's the equivalent to simply not being able to decode said piece of text.

LPCSTR, TCHAR, String

I am use next type of strings:
LPCSTR, TCHAR, String i want to convert:
from TCHAR to LPCSTR
from String to char
I convert from TCHAR to LPCSTR by that code:
RunPath = TEXT("C:\\1");
LPCSTR Path = (LPCSTR)RunPath;
From String to char i convert by that code:
SaveFileDialog^ saveFileDialog1 = gcnew SaveFileDialog;
saveFileDialog1->Title = "Сохранение файла-настроек";
saveFileDialog1->Filter = "bck files (*.bck)|*.bck";
saveFileDialog1->RestoreDirectory = true;
pin_ptr<const wchar_t> wch = TEXT("");
if ( saveFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK ) {
wch = PtrToStringChars(saveFileDialog1->FileName);
} else return;
ofstream os(wch, ios::binary);
My problem is that when i set "Configuration Properties -> General
Character Set in "Use Multi-Byte Character Set" the first part of code work correctly. But the second part of code return error C2440. When i set "Configuration Properties -> General
Character Set in "Use Unicode" the second part of code work correctly. But the first part of code return the only first character from TCHAR to LPCSTR.
I'd suggest you need to be using Unicode the whole way through.
LPCSTR is a "Long Pointer to a C-type String". That's typically not what you want when you're dealing with .Net methods. The char type in .Net is 16bits wide.
You also should not use the TEXT("") macro unless you're planning multiple builds using various character encodings. Try wrapping all your string literals with the _W("") macro instead and a pure unicode build if you can.
See if that helps.
PS. std::wstring is very handy in your scenario.
EDIT
You see only one character because the string is now unicode but you cast it as a regular string. Many or most of the Unicode characters in the ASCII range has their same number as in ASCII but have the second of their 2 bytes set to zero. So when a unicode string is read as a C-string you only see the first character because C-strings are null ( zero ) terminated. The easy ( and wrong ) way to deal with this is to use std:wstring to cast as a std:string then pull the C-String out of that. This is not the safe approach because Unicode has a much large character space then your standard encoding.

Resources