How can I evaluate a QChar object in a switch?

632 Views Asked by At

Going through a bunch of code, looking to improve it.

I came across this bit:

if (c == '<' || c == '>') {
    pattern.append("\\b");
} else if (c == 'a') {
    pattern.append("[a-zA-Z]");
} else if (c == 'A') {
    pattern.append("[^a-zA-Z]");
} else if (c == 'h') {
    pattern.append("[A-Za-z_]");
} else if (c == 'H') {
    pattern.append("[^A-Za-z_]");
} else if (c == 'c' || c == 'C') {
    ignorecase = (c == 'c');
} else if (c == 'l') {
    pattern.append("[a-z]");
} else if (c == 'L') {
    pattern.append("[^a-z]");
} else if (c == 'o') {
    pattern.append("[0-7]");
} else if (c == 'O') {
    pattern.append("[^0-7]");
} else if (c == 'u') {
    pattern.append("[A-Z]");
} else if (c == 'U') {
    pattern.append("[^A-Z]");
} else if (c == 'x') {
    pattern.append("[0-9A-Fa-f]");
} else if (c == 'X') {
    pattern.append("[^0-9A-Fa-f]");
} else if (c == '=') {
    pattern.append("?");
} else {
    pattern.append('\\');
    pattern.append(c);
}

If c was a char, this would be easy to turn into a switch. c is a QChar; How should I turn QChar into an interger and reliably compare it to the various cases >, = etc?

2

There are 2 best solutions below

1
Benjamin T On BEST ANSWER

A QChar is a wrapper for a 16-bit UTF-16 character.

You can retrieve the value using QChar::unicode() that returns an unsigned short.

You can the write your switch like this:

QChar c;
switch (c.unicode()) {
    case u'a':
    ...
}

Be careful with your case statements as if you use 8-bit char literals, it might not work as expected.

For instance é might be 0xE9 (Latin-1, UTF16), or 0x82 (CP437) or even 0xC3 0xA9 (UTF-8, which will not compile as it needs 2 characters).

The solution is to use UTF-16 literals that are part of C++ since C++11. For exampleu'é' will always be compiled as a char16_t (~unsigned short) of value 0x00E9.

1
ΦXocę 웃 Пepeúpa ツ On

you can define something like a dictionary, and I mean a Map:

int main(int argc, char* argv[])
{
    QMap<QChar, QString> myMap{{'a', "[a-zA-Z]"},{'X', "[^0-9A-Fa-f]"}, {'h', "[A-Za-z_]"}};

    QString regex{};
    regex.append(myMap.value('a', ""));
    regex.append(myMap.value('5', ""));
    regex.append(myMap.value('X', ""));
    qDebug() <<  "myRegex: " << regex;
    return 0;