c ++读取带重音的文件

c++ read file with accents

美好的一天,我在一个小项目中,我需要阅读 .txt 文件,问题是有些是英文的,有些是西班牙文的,正在展示的案例中有些信息带有重音和我必须用重音在控制台上显示它。

我在 setlocale(LC_CTYPE, "C");

的控制台上显示重音没问题

我的问题是在阅读中阅读 .txt 文件时,它没有检测到重音并读取罕见字符。

我的练习代码是:

#include <iostream>
#include <locale.h>
#include<fstream>
#include<string>

using namespace std;

int main(){
    
    setlocale (LC_CTYPE, "C");

    ifstream file;
    string text;
    
    file.open("entryDisciplineESP.txt",ios::in);
    
    if (file.fail()){
        
        cout<<"The file could not be opened."<<endl;
        
        exit(1); 
        
    }
    
    while(!file.eof()){ 

        getline(file,text);
        
        cout<<text<<endl;
        
    }
    
    cout<<endl;
    
    system("Pause");
    return 0;
}

有问题的 .txt 文件包含:

Inicio
D1
Biatlón
S1
255
E1
Esprint 7,5 km (M); 100; 200
E2
Persecucion 10 km (M); 100; 200
ff

显然我在使用“ó”时遇到了问题,但同样我还有其他带有重音符号的其他 .txt 字符,因此我需要针对所有这些字符的解决方案。

正在研究我已经阅读并尝试实现 wstring 和 wifstream,但我未能成功实现。

我正在尝试在 windows 上实现这一点,就像我需要解决方案在 linux 上工作一样,目前我正在使用 dev c++ 5.11

非常感谢您的宝贵时间和帮助。

你的错误在于你如何控制你的read-loop。请参阅:Why !.eof() inside a loop condition is always wrong. 相反,使用 read-function 返回的 stream-state 控制您的 read-loop,例如

    while (getline(file,text)) {
        
        std::cout << text << '\n';
        
    }

有问题的字符是简单的扩展 ASCII(例如 c3)并且很容易在 std::stringstd::cout 中表示。您的完整示例,修复 Why is “using namespace std;” considered bad practice? 将是

#include <iostream>
#include <fstream>
#include <string>

int main() {
    
    setlocale (LC_CTYPE, "C");

    std::ifstream file;
    std::string text;
    
    file.open ("entryDisciplineESP.txt");
    
    if (file.fail()){
        
        std::cerr << "The file could not be opened.\n";
        
        exit(1); 
    }
    
    while (getline(file,text)) {
        
        std::cout << text << '\n';
    }
    
    std::cout.put('\n');
    
#ifdef _WIN32
    system("Pause");
#endif
    return 0;
}

示例输出

$ ./bin/accent_read
Inicio
D1
Biatlón
S1
255
E1
Esprint 7,5 km (M); 100; 200
E2
Persecucion 10 km (M); 100; 200
ff

Windows 10 使用 UTF-8 代码页

您在 Windows 10 控制台下尝试 运行 上述代码时遇到的问题(我推测是 DevC++ 启动输出的地方)是默认代码页 (437 - OEM United States ) 不支持 UTF-8 字符。要将代码页更改为 UTF-8,您将使用 (65001 - Unicode (UTF-8))。参见 Code Page Identifiers

为了在使用 C++17 语言标准的 VS 下编译后获得正确的输出,所需要的只是在控制台中使用 chcp 65001 更改代码页。 (你还必须有UTF-8字体,我的是Lucida Console

设置代码页后在 Windows 控制台(命令提示符)中输出

C:\Users\david\source\repos\accents>chcp 65001
Active code page: 65001

C:\Users\david\source\repos\accents>Debug\accents.exe
Inicio
D1
Biatlón
S1
255
E1
Esprint 7,5 km (M); 100; 200
E2
Persecucion 10 km (M); 100; 200
ff

Press any key to continue . . .

由于 DevC++ 自动启动控制台,您还需要以编程方式设置代码页。您可以使用 SetConsoleOutputCP (65001) 来做到这一点。例如:

...
#include <windows.h>
...
#define CP_UTF8 65001 

int main () {

    // setlocale (LC_CTYPE, "C");           /* not needed */
    
    /* set console output codepage to UTF-8 */
    if (!SetConsoleOutputCP(CP_UTF8)) {
        std::cerr << "error: unable to set UTF-8 codepage.\n";
        return 1;
    }
    ...

参见 SetConsoleOutputCP function。设置输入代码页的类似函数是 SetConsoleCP(uint codepage).

使用 SetConsoleOutputCP() 输出

将控制台设置为默认 437 代码页,然后使用 SetConsoleOutputCP (65001) 将输出代码页设置为 UTF-8,你会得到相同的结果,例如

C:\Users\david\source\repos\accents>chcp 437
Active code page: 437

C:\Users\david\source\repos\accents>Debug\accents.exe
Inicio
D1
Biatlón
S1
255
E1
Esprint 7,5 km (M); 100; 200
E2
Persecucion 10 km (M); 100; 200
ff

Press any key to continue . . .

此外,检查 DevC++ 项目(或程序)设置并检查是否可以在那里设置输出代码页。 (我没用过,不知道可不可以)