5

コードにワイド文字列 (std::wstring) があり、ワイド文字を検索する必要があります。

そのために find() 関数を使用します。

    wcin >> str;
    wcout << ((str.find(L'ф') != wstring::npos)? L"EXIST":L"NONE");

L'ф'キリル文字です。

しかし、同じ呼び出しで find() は常に を返しますnpos。ラテン文字の場合、 find() は正しく機能します。

この機能の問題でしょうか?または、私は何かを間違っていますか?

UPD

MinGW を使用し、ソースを UTF-8 で保存します。でロケールも設定しましsetlocale(LC_ALL, "");た。コードは同じようwcout << L'ф';に動作します。でも同じ

wchar_t w;
wcin >> w;
wcout << w;

正しく動作しません。

変です。以前は、setlocale () を使用してエンコーディングに問題はありませんでした。

4

4 に答える 4

1

コンソールのエンコーディングを設定する必要があります。

これは機能します:

#include <iostream>
#include <string>
#include <io.h>
#include <fcntl.h>
#include <stdio.h>

using namespace std;

int main()
{       
    _setmode(_fileno(stdout), _O_U16TEXT);
    _setmode(_fileno(stdin), _O_U16TEXT);
    wstring str;
    wcin >> str;
    wcout << ((str.find(L'ф') != wstring::npos)? L"EXIST":L"NONE");
    system("pause");
    return 0;
}
于 2013-04-03T15:52:07.440 に答える
1

std::wstring::find()正常に動作します。ただし、入力文字列を正しく読み取る必要があります。

次のコードは、Windows コンソールで正常に実行されます (入力 Unicode 文字列はReadConsoleW()Win32 APIを使用して読み取られます)。

#include <exception>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <windows.h>
using namespace std;

class Win32Error : public runtime_error
{
public:
    Win32Error(const char* message, DWORD error)
        : runtime_error(message)
        , m_error(error)
    {}

    DWORD Error() const
    {
        return m_error;
    }

private:
    DWORD m_error;
};

void ThrowLastWin32(const char* message)
{
    const DWORD error = GetLastError();
    throw Win32Error(message, error);
}

void Test()
{
    const HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
    if (hStdIn == INVALID_HANDLE_VALUE)
        ThrowLastWin32("GetStdHandle failed.");

    static const int kBufferLen = 200;
    wchar_t buffer[kBufferLen];
    DWORD numRead = 0;

    if (! ReadConsoleW(hStdIn, buffer, kBufferLen, &numRead, nullptr))
        ThrowLastWin32("ReadConsoleW failed.");

    const wstring str(buffer, numRead - 2);

    static const wchar_t kEf = 0x0444;
    wcout << ((str.find(kEf) != wstring::npos) ? L"EXIST" : L"NONE");
}

int main()
{
    static const int kExitOk = 0;
    static const int kExitError = 1;

    try
    {
        Test();
        return kExitOk;
    }    
    catch(const Win32Error& e)
    {
        cerr << "\n*** ERROR: " << e.what() << '\n';
        cerr << "    (GetLastError returned " << e.Error() << ")\n";
        return kExitError;
    }
    catch(const exception& e)
    {
        cerr << "\n*** ERROR: " << e.what() << '\n';
        return kExitError;
    }        
}

出力:

C:\TEMP>test.exe
abc
NONE
C:\TEMP>test.exe
abcфabc
EXIST
于 2013-04-03T16:14:30.167 に答える