0

問題を切り分けるコードは次のとおりです。

#include <iostream>
#include <windows.h>

using namespace std;

int main() {
  SetConsoleOutputCP(CP_UTF8);
  _wsystem(L"echo pure ascii, naïveté");
  COORD pos = {0,0};

  TCHAR* attempt1 = new TCHAR[14];
  DWORD charnum1;
  ReadConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), attempt1, 14, pos, &charnum1);
  wcout << endl << "charnum1: " << charnum1 << ", attempt1: " << attempt1 << endl;
  wcout << "GetLastError: " << GetLastError();

  TCHAR* attempt2 = new TCHAR[16];
  DWORD charnum2;
  ReadConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), attempt2, 16, pos, &charnum2);
  wcout << endl << "charnum2: " << charnum2 << ", attempt2: " << attempt2 << endl;
  wcout << "GetLastError: " << GetLastError();

  system("pause > nul");
}

出力は次のとおりです。

pure ascii, naïveté

charnum1: 14, attempt1: pure ascii, na
GetLastError: 0
charnum2: 0, attempt2: x >
GetLastError: 0

最初の試行は問題なく動作しますが、関数が非 ASCII 文字で位置を読み込もうとすると、何も返されず、エラーも示されません。今何をする ?

4

1 に答える 1

2

警告: 私のシステムでは CP_UTF8 を使用できないため、コードを実行すると、echoコマンドは「システムは指定されたデバイスに書き込めません」という結果になります。

ただし、SetConsoleOutputCP()呼び出しを削除してデフォルトのコードページ 437 のままにしておくと、文字列が正しく表示されます。

個別の読み取りコードページと書き込みコードページがあることに注意してください。437、850、1252、および 28591 のさまざまな組み合わせを試しました。後者の 2 つは多かれ少なかれ Unicode の最初の 255 コードポイントに対応しています。CP_UTF8 が機能している場合は、 を呼び出してコードを再試行してくださいSetConsoleCP(CP_UTF8)

最後に読み取った文字の後に null を配置しないことに注意してください。そのReadConsoleOutputCharacter()ため、その TCHAR 配列を出力するときにコードに問題が発生します。null で終了するという保証はなく、クラッシュする可能性があります。(また、割り当てられた TCHAR 配列を削除しているのではありません。)したがって、割り当て行を次のように変更しました。

TCHAR attempt1[] = L"____________________";  // 20 underscores

これは(への呼び出しなしでSetConsoleOutputCP())これをもたらしました:

charnum1: 14, attempt1: pure ascii, na______
charnum2: 16, attempt2: pure ascii, na∩v____

2 行目の最後から 2 番目のグリフは「n」ではなく、コードページ 437 の文字 0xEF です。「ï」は Unicode の文字 0xEF です。ここで何が起こっているかというと、コンソールからは正しいコードポイント (0xEF) が読み取られましたが、ストリーム出力は引き続き 437 コードページを使用しています。ストリーム出力は、コンソールで設定されたコードページではなく、ストリームのロケール設定に基づいて文字を選択します。

コンソールの READ コードページがまだ 437 のときに、目的のコードポイント値がコンソールから読み取られる理由がわかりません。また、私SetConsoleOutputCP(1252)(または 28591) の場合、echoコマンドの出力が CP 437 を使用しているように見える理由についても困惑しています。 :pure ascii, na∩vitΘ

于 2012-06-06T00:18:23.357 に答える