wxString format Unicode character - c++

for(int i='א'; i<='ת'; i++)
incList.Add( wxString::Format("%c", wxT(i));
I'm trying to add Unicode character to the array using wxT. I'm getting this error
error: 'Li' was not declared in this scope
What is causing the error, and how can to fix it? Thanks.

wxT() is a macro defined thus:
#ifdef UNICODE
# define wxT(x) L##x
#else // !Unicode
# define wxT(x) x
#endif
So of course wxT(i) becomes Li. It should be used only with string literals.
Besides, why would wxT() convert an int to a string? Use itow for that.

wxT() is meant to operate on string literals, not variables.
You are probably wanting something along the lines of wxString::FromUTF8(chars) or wxString mystring2(chars, wxConvUTF8). Simply passing a char array as parameter works as well, but is depending on the current locale.
Oh, and while we're at it...
for(int i='א'; i<='ת'; i++)
...note that using characters outside of the basic character set (basically, ASCII-7) in C++ source is implementation-defined. You should probably use escape sequences instead.

Related

How to create string literal from -D compiler defined variable of a Windows path

Under Windows, I have an environment variable that contains a Windows-style path. I'd like to build that path into my program and print it out. So if my path is c:\top, I pass it into the compiler using -DTOP=$(TOP). Note I cannot convert it to c:\\top before I pass it into the compiler.
Right now, I have the equivalent of:
#define TOP=c:\top
I want the equivalent of:
char path[]="c:\\top";
I can't just use the stringafication operator:
#define WRAP1(X) #X
#define WRAP(X) WRAP1(X)
char path[] = WRAP(TOP);
That just results in the string "c:\top" which the compiler views as an escape sequence (i.e. \t).
I think a possible solution would be to construct a string literal, but other solutions will be also be fine. Is there a way to use macros to construct a string literal that would yield:
char path[] = R"foo(c:\top)foo";
So far, all my attempts have failed for reasons involving the variations of the " or ( ) or the \ .
Thanks.
You can convert your defined path to a string by prefixing it with the stringizing operator #. However, this only works in macros. You actually need a double-macro to make it work properly, otherwise it just prints TOP. Also placing the pathname in quotes is important - oh the example has the path stored under the env PathDirName
Defining the path for the compiler -
/DTOP="\"$(PathDirName)\\""
Using within the code
#define STRINGIZE2(x) #x
#define STRINGIZE(x) STRINGIZE2(x)
char path[] = STRINGIZE(TOP);
This has worked for me. You nearly had it working, so hope this helps.
[EDIT] I can see the problem now - within C:\top - its taking the 'backslash t' as a control code - '\t'. This appoarch is becoming a little bit of a nightmare to work out - as you really need to create the file name with two slashes or use forward slashes. I do feel I have confused issues here by answering before reviewing fully what has happened.
I have tried several methods - but not being able to change the passed in define - I can only suggest using a regex library or manual scanning the string - replacing the control charactors with the correct '\' letter.
I've knocked up an example showing this just with the '\t' in your example - It's not nice code, it's written to explain what is being done, hopefully it gives an visual example and it does (in a not so nice way) sort out the ONE issue you are having with 'C:\top' .. as I have said - if using this cough, method, you will need to handle all control codes. :-)
char stringName[256];
char* pRefStr = STRING(TOP);
char* pDestStr = stringName;
int nStrLen = strlen( pRefStr );
for( int nIndex = 0; nIndex < nStrLen; nIndex++ )
{
if ( *pRefStr == '\t' )
{
*pDestStr++ = '\\';
*pDestStr++ = 't';
pRefStr++;
}
else
{
*pDestStr++ = *pRefStr++;
}
}
*pDestStr = '\0';
Once again - sorry for any confusion - I've left my answer here as reference for you - and hopefully someone will come up with a way of handling the define-string (with the control charactors).
thanks, Neil
The rather bizarre syntax you're looking for performs on-the-fly substring replacement in variable expansion, as well as some quote mark escaping to make the definition a string. I found the substring replacement information here.
set DIR=C:\WINDOWS gets the env var set, and then we have a test prog:
#include <stdio.h>
#define STR(x) #x
#define STRING(x) STR(x)
int main( int argc, char* argv[] )
{
printf( "DIR: %s\n", STRING(DIR) );
return 0;
}
As you cannot quote in the shell, you can stringize here, but you must still do the variable substring replacement.
Pass the env var in through cmd.exe:
gcc -Wall -DDIR=%DIR:\=\\% main.c
See the link above for more information, or google substring replacement. I can't find a link to any Microsoft info on the function (what a surprise!)

Unicode range exceeds when try to print in C++

I am trying to print Unicode characters in C++. My Unicode characters are Old Turkic, I have the font. When I use a letter's code it gives me another characters. For example:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str = "\u10C00" // My character's unicode code.
cout << str << endl;
return 0;
}
This snipped gives an output of another letter with a 0 just after its end.
For example, it gives me this (lets assume that I want to print 'Ö' letter):
A0
But when I copied and pasted my actual letter to my source snippet, from character-map application in ubuntu, it gives me what I want. What is the problem here? I mean, I want use the character code way "\u10C00", but it doesn't work properly. I think this string is too long, so it uses the first 6 characters and pops out the 0 at the end. How can I fix this?
After escape /u must be exactly 4 hexadecimal characters. If you need more, you should use /U. The second variant takes 8 characters.
Example:
"\u00D6" // 'Ö' letter
"\u10C00" // incorrect escape code!
"\U00010C00" // your character
std::string does not really support unicode, use std::wstring instead.
but even std::wstring could have problems since it does not support all sizes.
an alternative would be to use some external string class such as Glib::ustring if you use gtkmm or QString in case of Qt.
Almost each GUI toolkit and other libraries provide it's own string class to handle unicode.

vector<string> in wxComboBox

I hope my question is not to localized... But I think some other will stumble about this or a similar problem.
I want to create a vector which contains all available ports at my system (this works in a console app). After that I want to copy the vectorelements in a wxString-Array to get them in a wxComboBox.
So, in my particular case I get two errors:
the variablename of the vector is not known in wxWidgets
by copying, the wxString will cast my string into a wchar_t (I know, wchar_t and wxString are similar...)
I will add some of my Code, so you will have a better sight about the problem:
first problem
std::vector<std::string> v_ports;
v_ports.push_back = "Com1";
v_ports.push_back = "Com4";
--> error: 'v_ports' does not name a type
(hint: that is a example, in the hole programm I will use a function to get the strings)
second problem
wxString sect_opt[v_ports.size()];
for(int i = 0; i < v_ports.size(); i++)
sect_opt[i] = _T(v_ports[i]);
--> error: 'Lv_ports' was not declared in this scope
I'm using:
IDE: CodeLite 5.1; wxW 2.9.4; #Win8.1
First problem
Instead of using:
v_ports.push_back = "Com1";
v_ports.push_back = "Com4";
you should use:
v_ports.push_back("Com1");
v_ports.push_back("Com4");
because std::vector<T>::push_back is a function.
Second problem
The _T macro is supposed to be used on literals:
Use the _T macro to conditionally code literal strings to be portable to Unicode.
It cannot be used in expressions like _T(v_ports[i]).
To convert a string to unicode please see:
Converting unicode strings and vice-versa (Philipp's answer)
How well is Unicode supported in C++11?

What's the point of this kind of macros?

#define NAME(x) TEXT(x)
#define TEXT(quote) __TEXT(quote) // r_winnt
#define __TEXT(quote) quote // r_winnt
The above is from winNT.h, isn't NAME("Virtual Cam") the same as "Virtual Cam",what's the point to use this macro?
__TEXT macro expansion is selected based on whether UNICODE flag is defined or not. If not it just expands to quote else it will append L to the quote so that it becomes L"Virtual Cam" . This string is interpreted as a wide char string.
Depends on if your system is #defined to use Unicode. Then it will automatically change the literal for you to be a wide literal instead of a char literal.

TCHAR[], LPWSTR, LPTSTR and GetWindow Text function

So the GetWindowText is declared on MSDN as follows:
int GetWindowText(
HWND hWnd,
LPTSTR lpString,
int nMaxCount
);
However for the code to work we have to declare the second parameter as
TCHAR[255] WTitle;
and then call the function GetWindowText(hWnd,Wtitle,255);
The LPTSTR is a pointer to an array of tchar, so declaring LPTSTR is similar to declaring TCHAR[]? It doesn't work this way though.
When using TCHAR[] the program returns valid GetWindowText result (it is an integer equal to the number of symbols in the title). The question is : how can I get the exact title out of TCHAR[] ? Code like
TCHAR[255] WTitle;
cout<< WTitle;
or
cout<< *Wtitle;
returns numbers. How can I compare this with a given string?
TCHAR[4] Test= __T("TEST")
if (WTitle == Test) do smth
doesn't work also.
Wow, let's see where to start from.
First off, the declaration of WTitle needs to look like this:
TCHAR WTitle[255];
Next, if cout is not working write, it's because you are in Unicode mode so you need to do this:
wcout << WTitle;
Or to fit better with the whole tchar framework, you can add this (actually, I'm surprised that this is not already part of tchar.h):
#ifdef _UNICODE
#define tcout wcout
#else
#define tcout cout
#endif
and then use:
tcout << WTitle;
OK, a few definitions first.
The 'T' types are definitions that will evaluate to either CHAR (single byte) or WCHAR (double-byte), depending upon whether you've got the _UNICODE symbol defined in your build settings. The intent is to let you target both ANSI and UNICODE with a single set of source code.
The definitions:
TCHAR title[100];
TCHAR * pszTitle;
...are not equivalent. The first defines a buffer of 100 TCHARs. The second defines a pointer to one or more TCHARs, but doesn't point it at a buffer. Further,
sizeof(title) == 100 (or 200, if _UNICODE symbol is defined)
sizeof(pszTitle) == 4 (size of a pointer in Win32)
If you have a function like this:
void foo(LPCTSTR str);
...you can pass either of the above two variables in:
foo(title); // passes in the address of title[0]
foo(pszTitle); // passes in a copy of the pointer value
OK, so the reason you're getting numbers is probably because you do have UNICODE defined (so characters are wide), and you're using cout, which is specific to single-byte characters. Use wcout instead:
wcout << title;
Finally, these won't work:
TCHAR[4] Test == __T("TEST") ("==" is equality comparison, not assignment)
if (WTitle == Test) do smth (you're comparing pointers, use wcscmp or similar)
Short answer: Unless you're coding for Win98, use wchar_t instead of TCHAR and wcout instead of cout
Long version:
The TCHAR type exists to allow for code to be compiled in multiple string modes. For example supporting ASCII and Unicode. The TCHAR type will conditionally compile to the appropriate character type based no the setting.
All new Win systems are Unicode based. When ASCII strings are passed to OS functions, they are converted to unicode and the call the real function. So it's best to just use Unicode throughout your application.
Use _tcscmp or a variant (which takes in the number of characters to compare). http://msdn.microsoft.com/en-us/library/e0z9k731.aspx
Like:
if (_tcscmp(WTitle, Test) == 0) {
// They are equal! Do something.
}
In C, wchar_t is a typedef for some integer type (usually short int). In C++, it's required to be a separate type of its own -- but Microsoft's compilers default to using a typedef for it anyway. To make it a separate type of its own, you need to use the /Zc:wchar_t compiler switch. Offhand, I don't know if that will entirely fix the problem though -- I'm not sure if the library has real overloads for wchar_t as a native type to print those out as characters instead of short ints.
Generally speaking, however, I'd advise against messing with Microsoft's "T" variants anyway -- getting them right is a pain, and they were intended primarily to provide compatibility with 16-bit Windows anyway. Given that it's now been about 10 years since the last release in that line, it's probably safe to ignore it in new code unless you're really sure at least a few of your customers really use it.