【问题标题】:Cant work with characters like á à ã ă â é è ê无法使用 á à ã ă â é è ê 等字符
【发布时间】:2021-06-09 13:16:50
【问题描述】:

我的代码应该清除任何不是a-zA-Z 的字符。对于其他字符,例如á à ã ă â é è ê,如果我可以使其工作,我会让它们从á 更改为aè 更改为e 等。

#include <iostream>
#include <string>

using namespace std;

int main()
{
    int counter=0;
    string* word = new string[1];
    string b ="áhelloá";//nothing

    word[0] = "áapple_.Dogá.";//doesnt work
    //word[0] = "apple_.Dog.";//if there is no characters like á it works
    cout<<endl<<word[0].length()<<endl;

    for (int i = 0; i < word[0].length(); ++i)
    {
        if(word[0][i] >= 'A' && word[0][i] <='Z' || word[0][i] >= 'a' && word[0][i] <='z')
        {
            cout<<"Current: "<<word[0][i]<<endl;//shows what characters passed if
        }
        else
        {
            cout<<"Erased: "<<word[0][i]<<endl;//shows what was erased
            word[0].erase(i,1);//deletes char
            i--;
        }
    }

    cout<<endl<<word[0];//prints final word,after erase

    return 0;
}

如果我在Clion 中使用例如á 运行我的代码,它不会执行任何操作并返回0。我在Repl.it 上进行了相同的测试,我认为它在某种程度上按预期工作。我的Clion 有问题吗?我做错了什么?

【问题讨论】:

  • char 无法表示非 ASCII 字符。您需要 utf-8 或其他编码方案来处理字符。你需要一个不是 std::string 的不同的。
  • @FredLarson 为什么它适用于 Replit?我查看了一些关于 unicode 的帖子,但它对我来说有点复杂,而且我也没有一些库。
  • 您必须使用std::wstringstd::wcoutL"abcdef"。另外:你是从哪里学习 c++ 的?!为什么你无缘无故地使用动态数组?!还使用命名空间 std 和 endl!
  • @Jesepy 还有std::string 在某些操作系统上可能就足够了(例如,它可以在我的 Mac 上运行),但在其他操作系统上就不行了。

标签: c++ string text ascii extended-ascii


【解决方案1】:

您可以使用wcoutwstring 在Windows 中处理C++ 中的Unicode 字符:

#include <iostream>
#include <string>
#include <io.h>
#include <fcntl.h>
using namespace std;

int main()
{
    _setmode(_fileno(stdout), _O_U16TEXT); //set the mode of the output file handle to take only UTF-16 data
    int counter=0;
    wstring word;

    word = L"áapple_.Dogá.";
    cout<<'\n'<<word.length()<<'\n';

    for (int i = 0; i < word.length(); ++i)
    {
        if(word[i] >= 'A' && word[i] <='Z' || word[i] >= 'a' && word[i] <='z')
        {
            wcout<<"Current: "<<word[i]<<'\n';
        }
        else
        {
            wcout<<"Erased: "<<word[i]<<'\n';
            word.erase(i,1);
            i--;
        }
    }

    wcout<<'\n'<<word;
    return 0;
}

结果:

Erased: á
Current: a
Current: p
Current: p
Current: l
Current: e
Erased: _
Erased: .
Current: D
Current: o
Current: g
Erased: á
Erased: .

appleDog

对于“为什么它适用于 repl.it?”这个问题:

需要注意的是,不同的编译器和平台处理 Unicode 字符非常不同。引用@bames53:

#include <iostream>

int main() {
    std::cout << "Hello, ф or \u0444!\n"; }

此程序不要求 'ф' 可以用单个表示 字符。在 OS X 和大多数现代 Linux 安装上,这将只工作 很好,因为源代码、执行代码和控制台编码都是 UTF-8(支持所有 Unicode 字符)。

使用 Windows 更难,并且有不同的可能性 有不同的权衡。

顺便说一句,IMO 您无缘无故地使用动态数组。 wstring 就足够了。

另见

【讨论】:

  • 我不得不将 _O_U16TEXT 更改为 0x00020000,因为它说在这个范围内未声明,为什么会这样。我认为它很好用,谢谢
  • @Jesepy 在您的编译器中可能不可用。解决方法在此post
  • 是的,这就是我找到它的地方
猜你喜欢
  • 2020-05-05
  • 1970-01-01
  • 2013-07-20
  • 1970-01-01
  • 2018-08-28
  • 2017-04-16
  • 1970-01-01
  • 2012-12-21
  • 2012-04-26
相关资源
最近更新 更多