gpt4 book ai didi

c++ - MinGW 下带有 boost::filestream 的 UTF-8 名称

转载 作者:行者123 更新时间:2023-11-30 03:28:39 24 4
gpt4 key购买 nike

我遇到了boost filestreams的问题:我需要在windows下的用户目录下创建和修改文件。然而,用户名包含一个变音符号,这使得在 MinGW 下编译时失败,因为标准缺少用于 boost 使用的文件流的 wide_char open() API。见Read/Write file with unicode file name with plain C++/Boost , UTF-8-compliant IOstreamshttps://svn.boost.org/trac10/ticket/9968

但是我发现这个问题主要发生在尝试使用系统代码页之外的字符时。在我的例子中,我只使用系统代码页中的字符,因为显然用户目录存在。这让我觉得,如果我可以告诉 boost::path 期望所有 std::string 都是 UTF8 但在调用 string 时将它们转换为系统编码,这应该可行() 成员函数(发生在 boost::fstream::open 中)

基本上:有什么方法可以使用 boost(和 boost Locale)自动进行转换(UTF8->系统编码)?

这里是我设置语言环境的代码:

#ifdef _WIN32
// On windows we want to enforce the encoding (mostly UTF8). Also using "" would use the default which uses "wrong" separators
std::locale::global(boost::locale::generator().generate("C"));
#else
// In linux / OSX this suffices
std::locale::global(std::locale::classic());
#endif // _WIN32
// Use also the encoding (mostly UTF8) for bfs paths
bfs::path::imbue(std::locale());

最佳答案

这是 Windows 上的问题,因为 Windows 使用 UTF-16,而不是 UTF-8。我经常使用此功能来解决您的问题:

// get_filename_token.cpp

// Turns a UTF-8 filename into something you can pass to fstream::open() on
// Windows. Returns the argument on other systems.

// Copyright 2013 Michael Thomas Greer
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt )

#ifdef _WIN32

#include <string>

#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>

std::string get_filename_token( const std::string& filename )
{
// Convert the UTF-8 argument path to a Windows-friendly UTF-16 path
wchar_t* widepath = new wchar_t[ filename.length() + 1 ];
MultiByteToWideChar( CP_UTF8, 0, filename.c_str(), -1, widepath, filename.length() + 1 );

// Now get the 8.5 version of the name
DWORD n = GetShortPathNameW( widepath, NULL, 0 );
wchar_t* shortpath = new wchar_t[ n ];
GetShortPathNameW( widepath, shortpath, n );

// Convert the short version back to a C++-friendly char version
n = WideCharToMultiByte( CP_UTF8, 0, shortpath, -1, NULL, 0, NULL, NULL );
char* ansipath = new char[ n ];
WideCharToMultiByte( CP_UTF8, 0, shortpath, -1, ansipath, n, NULL, NULL );

std::string result( ansipath );

delete [] ansipath;
delete [] shortpath;
delete [] widepath;

return result;
}

#else

std::string get_filename_token( const std::string& filename )
{
// For all other systems, just return the argument UTF-8 string.
return filename;
}

#endif

(我已经删除了一些要发布的内容。)

关于c++ - MinGW 下带有 boost::filestream 的 UTF-8 名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46397007/

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