3

私はフランス語でプログラミングしているため、アクセント付きの文字を使用する必要があります。#include <locale>とを使って出力できます setlocale(LC_ALL, "")が、アクセント付きの文字を読むと問題があるようです。問題を示すために作成した簡単な例を次に示します。

#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;
}

プログラムがクラッシュする前の出力例を次に示します。

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

Visual Studio のデバッガーが、出力されるものとは異なるものを作成したことを示していることに気付きました。

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

表示されたエラーは、-1 から 255 までの文字のみを使用できることを示しているようですが、 ASCII テーブルによると、上記の例で使用したアクセント付き文字の値はこの制限を超えていません

ポップアップするエラー ダイアログの図を次に示します。エラー メッセージ: 式: c >= -1 && c <= 255

誰かが私が間違っていることを教えてくれますか、それとも解決策を教えてもらえますか? 前もって感謝します。:)

4

2 に答える 2

1

is*および関数では、入力を関数に渡す前to*にキャストする必要があります。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 に答える