gpt4 book ai didi

c++ - 如何使用标准 API 打开和读取具有 unicode 路径或文件名的文件的内容?

转载 作者:太空宇宙 更新时间:2023-11-04 13:43:56 27 4
gpt4 key购买 nike

如何在不使用任何特殊 API 的情况下打开路径或文件名包含 unicode 字符的文件并读取或写入其内容?。如果可能,如何仅使用标准库或仅使用 Windows API?我确实尝试 std::wifstream 打开一个文件,如下面的代码示例所示,但它没有编译。看起来它不需要“const wchar_t*”参数,而是“const char*”。我正在使用 Dev-C++ IDE 中包含的 TDM-GCC 4.7.1 编译器。

#ifndef UNICODE
#define UNICODE
#endif
...
#include <clocale>
#include <windows.h>
#include <fstream>
...
int main(int argc, char **argv)
{
setlocale(LC_ALL, "Polish_Poland.852") ;
...
fileCompare(first, second) ;
...
}
...
bool fileCompare(wstring first, wstring second) // This function doesn't compile !
{
using namespace std ;
wifstream fin0(first.c_str(), ios::binary) ;
wifstream fin1(second.c_str(), ios::binary) ;
...
}

一些完整的例子:

#ifndef UNICODE
#define UNICODE
#endif

#include <clocale>
#include <conio.h>
#include <windows.h>
#include <fstream>
#include <string>
#include <iostream>

using namespace std ;

bool fileCompare(wstring first, wstring second) ;

int main(int argc, char **argv)
{
setlocale(LC_ALL, "Polish_Poland.852") ;

wstring first, second ;
first = L"C:\\A.dat" ;
second = L"C:\\E.dat" ;

fileCompare(first, second) ;

getch() ;
return 0 ;
}

bool fileCompare(wstring first, wstring second) // This function doesn't compile !
{
wifstream fin0(first.c_str(), ios::binary) ;
wifstream fin1(second.c_str(), ios::binary) ;

}

此外,当我将 L"C:\A.dat"和 L"C:\E.dat"替换为包含波兰语字符的字符串时,它会输出有关非法字节序列的错误。

最佳答案

wifstream 不处理文件名编码问题。据我所知,wifstream 和 ifstream 的文件名都是基于 char 而不是基于 wchar_t 的。您必须以操作系统使用的 char 编码提供文件名,例如latin1, utf8 等..

然而,wifstream 使您能够读取 wchar_t 流。您可以通过 imbuing 流告诉流您期望什么输入:

例如

 // We expect the file to be UTF8 encoded
std::locale locale("en_US.utf8");
fin0.imbue(locale);

编辑:如果您需要将文件名(或任何字符串)从 wchar_t 转换为适当的字符编码,您可以更深入地研究 codecvt facets 的主题。语言环境。

// Method translates wchar_t => pl_PL.iso88592" encoding
std::string to_string(const std::wstring & wstr)
{

typedef std::codecvt< wchar_t, char, std::mbstate_t > ccvt_t;

std::locale loc("pl_PL.iso88592");

const ccvt_t & facet = std::use_facet<ccvt_t>( loc );

std::string s;
{
std::mbstate_t st=mbstate_t();

const wchar_t *wac = wstr.c_str();
const wchar_t *wou = wac + wstr.length();
const wchar_t *wnx = wac;

ccvt_t::result r = ccvt_t::ok;

while(wou!=wnx && (r==ccvt_t::ok || r==ccvt_t::partial))
{
static const int l = 100;
static char cou[l];
char *cnx=NULL;
r = facet.out(st,wac,wou,wnx,cou,cou+l,cnx);
s+=std::string(cou,cnx-cou);
wac=wnx;
}
}

return s;
}

支持哪种 std::locale 以及您如何指定它可能取决于操作系统。

关于c++ - 如何使用标准 API 打开和读取具有 unicode 路径或文件名的文件的内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26700115/

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