1

私は C++ で開発を始めており、コンソールで簡単な電卓を開発しています。プログラムが終了するかどうかをユーザーに尋ねると、文字「¿」が表示されません (スペイン語の質問は「¿」と「?」の間にあります)。 ')

誰かが私を助けることができますか?

PD: この問題は Windows でのみ発生し、Linux では発生しません

編集:コードを出力するコードは次のとおりです。

cout << '¿' <<"Desea salir (S/N)? " ;
4

6 に答える 6

3

この問題に対処するには、いくつかの方法があります。

根本的な問題は¿、コンソールに が存在しないことではなく、コンソールと C++ テキスト エディターがその文字が何であるかについて意見が一致しないことです。この 2 つは、英語に必要な文字数を超えて、多くの文字に異なる文字コードを使用しています。文字コード 32 ~ 126 (文字、数字、句読点、括弧) は、一般的に同じです。ただし、文字コード 128 ~ 255 は、スペイン語の観点からは、すべてのアクセント付き文字、「分音符付きの u」(例:「pingüino」)、Ñ、および開始の ¿ と ¡ を含み、特定の環境に依存します。

文字コードにこのような不都合な不一致があるのは歴史的な偶然であり、それ自体は興味深いものですが、この質問の範囲外です。簡単に言うと、Windows OS では、「コンソール」(通常) はOEM Code Page 437で説明されている文字のリストを使用しますが、C++ エディターのような Windows アプリケーションは (通常) Windows-1252 Code Page を使用します。

異なる文字セットの問題はプラットフォーム固有の問題であるため、この問題に対する移植可能な (普遍的な) 解決策はありません。残念ながら、Windows は、エディターと (コンソール) 出力が異なるセットを使用するという点で、やや独特です。

最初の最も簡単な解決策 (おもちゃのプログラムでは問題ありません) は、必要な文字コードを OEM 437 コード ページから検索し、それを使用することです。の場合¿は #168 (16 進数で 0xa8、8 進数で \250) です。文字コードを文字列に埋め込むだけで、何をしようとしているのかを明確にすることができます。次のいずれかです。

std::cout << ""\x0a8""Cu""\x0a0""l es el primer n""\x0a3""mero?\n"; // hex
std::cout << "\250Cu\240l es el primer n\243mero?\n";  // octal

出力:

¿Cuál es el primer número?

ú と á で同じことをしなければならなかったことに注意してください。残念ながら、このような文字列を書くとすぐに扱いにくくなります。マクロやconst chars を使用すると役に立ちますが、それほど多くはありません。

2 番目の代替手段は、などの Windows 関数を使用することCharToOemAです。例1 :

#include <windows.h>
...
...
char pregunta[] = "¿Cuál es el primer número\n";
char *pregunta_oem  = new char[sizeof(pregunta)/sizeof(char)];
CharToOemA(pregunta, pregunta_oem);
std::cout << pregunta_oem;
delete []pregunta_oem;

より複雑なプログラムの場合、そのパターンをユーティリティ関数またはクラスにラップします。

別の方法として、コンソールのコード ページを変更して、C++ エディターおよびその他の Windows と一致するようにします。これは、CHCP コンソール コマンドまたは SetConsoleOutputCP() 関数を使用して実行できますが、コンソールで使用されるデフォルトの「ラスター フォント」では機能しないため、フォントも変更する必要があります。フォントが Lucida Console のような Unicode フォントに設定されている場合、これは機能します。

std::cout << "¿Cuál es el primer número?\n"; // ┐Cußl es el...
UINT originalCP = GetConsoleOutputCP();
SetConsoleOutputCP(1252);
std::cout << "¿Cuál es el primer número?\n"; // ¿Cuál es el...
SetConsoleOutputCP(originalCP);

(プログラム自体からフォントを変更できるかどうかはわかりません。調べる必要があります。コンソールから行う標準的な方法は、隅にある小さなアイコンをクリックし、[プロパティ]、[フォント] タブ、リストからフォントを選択します)。


1このスニペットには、初心者を簡単につまずかせる可能性のある多くの微妙な点が含まれていることを警告する必要があります。テキストのソースが char 配列であることを確認する必要があります。char ポインターを使用している場合、sizeof正しく動作しないため、strlen(source)+1. ソースには、リテラルに初期化された char 配列の自然なオプションを使用しましたが、そのような配列の内容は読み取り専用であるため、宛先にはそれを行うことはできません。新しい char 配列またはリテラルに初期化されていないものを使用している場合は、ソースと宛先に同じ char 配列を使用できます。この例は非常に C に似ています。

于 2013-07-23T14:48:52.800 に答える
2

_setmode関数を使用してそれを行うことができます:

#include <iostream>
#include <string>

#if defined(WIN32) && !defined(UNIX)
# include <io.h>    // for _setmode()
# include <fcntl.h> // for _O_U16TEXT
#endif // WIN32 && !UNIX

int main()
{
#if defined(WIN32) && !defined(UNIX)
    _setmode(_fileno(stdout), _O_U16TEXT);
  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#endif // WIN32 && !UNIX

    std::wstring wstr = L"'¿' and '?'";

    std::wcout << L"WString : " << wstr << std::endl;
    system("pause");
    return 0;
}

UNICODE 文字 (LE が UTF-16 の標準的な Windows バリアントであると仮定して...) を iostream ライブラリで書き出すには、_O_U16TEXT で _setmode() を呼び出してから、wcout を使用します。

でも、もう使えcoutません。アサートをスローします。

この回答を確認してください。

于 2013-07-23T11:37:12.210 に答える
0

この文字は、基本的な ascii には含まれていません。wstring http://www.cplusplus.com/reference/string/wstring/を使用してみてください

于 2013-07-23T11:26:19.413 に答える
0

Ascii tableでわかるように、シンボル ¿ にはコード 168 があります。出力ストリームで \ddd を使用して、特殊文字を出力できます。

于 2013-07-23T11:32:56.540 に答える