3

I am programming in French and, because of that, I need to use accented characters. I can output them by using #include <locale> and setlocale(LC_ALL, ""), but there seems to be a problem when I read accented characters. Here is simple example I made to show the problem :

#include <locale>
#include <iostream>

using namespace std;

const string SymbolsAllowed = "+-*/%";

int main()
{
    setlocale(LC_ALL, "");    // makes accents printable

    // Traduction : Please write a string with accented characters
    // 'é' is shown correctly :
    cout << "Veuillez écrire du texte accentué : ";

    string accentedString;
    getline(cin, accentedString);

    // Accented char are not shown correctly :
    cout << "Accented string written : " << accentedString << endl;

    for (unsigned int i = 0; i < accentedString.length(); ++i)
    {
        char currentChar = accentedString.at(i);

        // The program crashes while testing if currentChar is alphanumeric.
        // (error image below) :
        if (!isalnum(currentChar) && !strchr(SymbolsAllowed.c_str(), currentChar))
        {
            cout << endl << "Character not allowed : " << currentChar << endl;
            system("pause");
            return 1;
        }
    }

    cout << endl << "No unauthorized characters were written." << endl;

    system("pause");
    return 0;
}

Here is an output example before the program crashes :

Veuillez écrire du texte accentué : éèàìù
Accented string written : ʾS.?—

I noticed the debugger from Visual Studio shows that I have written something different than what it outputs :

[0] -126 '‚'    char
[1] -118 'Š'    char
[2] -123 '…'    char
[3] -115 ''     char
[4] -105 '—'    char

The error shown seems to tell that only characters between -1 and 255 can be used but, according to the ASCII table the value of the accented characters I used in the example above do not exceed this limit.

Here is a picture of the error dialog that pops up : Error message: Expression: c >= -1 && c <= 255

Can someone please tell me what I am doing wrong or give me a solution for this? Thank you in advance. :)

4

2 回答 2

1
于 2015-12-19T02:25:24.407 回答
1

使用is*andto*函数,您确实需要在将输入unsigned char传递给函数之前将其转换为:

if (!isalnum((unsigned char)currentChar) && !strchr(SymbolsAllowed.c_str(), currentChar)) {

当您使用它时,我建议您不要使用strchr它,并切换到这样的东西:

std::string SymbolsAllowed = "+-*/%";

if (... && SymbolsAllowed.find(currentChar) == std::string::npos)

当您使用它时,您可能应该忘记您甚至听说过exit功能。你永远不应该在 C++ 中使用它。在这种情况下(从 退出main)你应该只是return. 否则,抛出异常(如果你想退出程序,捕获异常main并从那里返回)。

如果我写这篇文章,我会以不同的方式完成这项工作。std::string已经有一个函数可以完成你的循环试图完成的大部分工作,所以我设置symbolsAllowed为包含你想要允许的所有符号,然后只需搜索它不包含的任何内容:

// Add all the authorized characters to the string:
for (unsigned char a = 0; a < std::numeric_limits<unsigned char>::max(); a++)
    if (isalnum(a) || isspace(a)) // you probably want to allow spaces?
        symbolsAllowed += a;

// ...

auto pos = accentedString.find_first_not_of(symbolsAllowed);
if (pos != std::string::npos) {
    std::cout << "Character not allowed: " << accentedString[pos];
    return 1;
}
于 2015-12-19T02:26:06.493 回答