gpt4 book ai didi

c++ - 在 C++ 中使用 std::ifstream 读取 ASCII 文本文件

转载 作者:太空宇宙 更新时间:2023-11-04 14:29:53 26 4
gpt4 key购买 nike

我有一个阿拉伯文文件 (ASCII),其中包含:121101 阿拉伯语121102 阿拉伯语121103 阿拉伯语

我想使用 C++ 中的 std::ifstream 读取此文件:

std::ifstream ifs(file.GetFileName());
std::string content((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());

当我使用 VS IDE 观看内容变量时,出现字符编码错误:121101 ÇáÒÈæä ßãÇá121102 ÇáÒÈæä ÓÚíÏ121103 ÇáÒÈæä ÚãÇÇ

我还有托盘 std::wifstream:

std::wifstream ifs2(file.GetFileName());
std::string content2((std::istreambuf_iterator<wchar_t>(ifs2)), std::istreambuf_iterator<wchar_t>());

我遇到了同样的错误。有人可以帮助我吗?谢谢。

最佳答案

I have an Arabic file (ASCII), which contains: 121101 الزبون كمال 121102 الزبون سعيد 121103 الزبون عمار

经过一番澄清后,OP 想要:

to write general function which read uft8 and ANSI files

为了能够以相同的方式处理内容,我建议转换为 UTF-16 编码的 std::wstring。 OP 似乎是为 Windows 平台开发的,其中 UTF-16 是大多数 API 所期望的编码。在其他平台 (Linux) 上,将所有内容都转换为 UTF-8 可能更合适。

将 ANSI 文本文件读入 UTF-16 编码的 wstring

为了能够解码 ANSI(又名扩展 ASCII),我们必须知道 codepage的文件。

可以通过流的 imbue() 定义代码页(或更准确地说是语言环境)方法。在您的情况下,代码页是 1256 .

以下示例读取使用 ANSI 代码页 1256 编码的文本文件的内容,并使用需要 UTF-16 编码字符串的 MessageBoxW() 显示文本:

#include <fstream>
#include <string>
#include <codecvt>
#include <Windows.h>

int main()
{
// Use wifstream because we want to read content into a wstring.
std::wifstream f{"test.txt"};

// Define the code page of the text file (1256 = Arabic)
f.imbue( std::locale( ".1256" ) );

// Read the whole file into a wstring.
// The stream converts from ANSI to UTF-16 encoding.
std::wstring s{ std::istreambuf_iterator<wchar_t>( f ), std::istreambuf_iterator<wchar_t>() };

// Display the string which is now UTF-16 encoded.
::MessageBoxW( NULL, s.c_str(), L"test", 0 );

return 0;
}

注意:std::locale 参数是特定于平台的。 “.1256”适用于 Windows 平台,但可能不适用于 Linux 等平台。

将UTF-8编码的文本文件读入UTF-16编码的wstring

为此我们可以使用 std::codecvt_utf8_utf16方面。替换 imbue()使用以下代码调用上一个示例:

    f.imbue( std::locale( f.getloc(), 
new std::codecvt_utf8_utf16< wchar_t, 1114111UL, std::consume_header> ) );

标志 std::consume_header 跳过 byte order mark如果它存在。

注意事项:

  • 代码示例已在 Windows 10 下使用 VS2017 进行了测试,本地化为德语。
  • 为简洁起见,我省略了错误处理。应在打开后和从流中读取后检查流状态。

创建通用解决方案

上面提供的代码示例要求您事先了解文本文件的编码。以真正通用的方式检测文本文件的编码是一项艰巨的任务,因为没有标准的方法可以做到这一点。它无法可靠地完成,您必须使用一些启发式方法。

如果您可以对必须处理的文件做出一些假设,那么您可以编写一个简单的检测函数。假设文件仅属于以下类别:

  • 代码页为 1256 的 ANSI 编码文件
  • 带有 BOM 的 UTF-8 编码文件 ( byte order mark )

然后您可以使用 std::ifstream 读取文件的前 3 个字节,并将它们与 {0xEF, 0xBB, 0xBF} 进行比较。如果相等,您可以相对确定该文件是 UTF-8 编码的,因为非 UTF-8 编码的文件不太可能以这些字节开头。如果不相等,您将假定代码页为 1256。

关于c++ - 在 C++ 中使用 std::ifstream 读取 ASCII 文本文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43026852/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com