相关疑难解决方法(0)

如何使用unicode filename c ++读取二进制文件?

在我正在研究的项目中,我处理了很多字符串操作; 从二进制文件中读取字符串及其编码(可以是单字节或双字节).本质上,我读取字符串值为vector<char>,读取编码,然后将所有字符串转换为wstring,以保持一致性.

这工作得相当好,但文件名本身可以是双字节字符.我完全不知道如何实际打开输入流.在CI中会使用_wfopen函数传递wchar_t* path,但wifstream似乎表现不同,因为它专门用于从文件中读取双字节字符,而不是从具有双字节文件名的文件中读取单个字节.

这个问题的解决方案是什么?

编辑:搜索网络,看起来在标准C++中根本不支持这一点(例如,请参阅此讨论).但是我想知道C++ 11是否真的在这方面添加了一些有用的东西.

c++ unicode ifstream c++11

10
推荐指数
1
解决办法
1537
查看次数

为什么STL ifstream和ofstream类不将std :: string作为文件名?

这是对STL的抱怨.为什么他们将文件名参数作为(char*)而不是作为std :: string?这似乎毫无意义.

关于这个主题还有另外两个问题:

问题是我有很多代码如下:

    std::ofstream f(fname.c_str());
Run Code Online (Sandbox Code Playgroud)

当我希望它看起来像这样:

std::ofstream f(fname);
Run Code Online (Sandbox Code Playgroud)

上述帖子中提到的其他问题是UTF-16与UTF-8的问题.(UTF-16可能包含会破坏POSIX API的NULL).但这不是一个真正的问题,因为实现可以在调用open()之前将UTF-16转换为UTF-8.

但严重的是,这没有任何意义.有没有计划升级STL?

c++ iostream stl

9
推荐指数
1
解决办法
3292
查看次数

如何在C ++ 20中安全地将const char *转换为const char8_t *?

这个答案中,我了解到在C ++ 17中,我们可以std::fstream通过使用UTF-8路径打开std::filesystem::u8path。但是在C ++ 20中,不建议使用此函数,而应该将其传递const char8_t*std::filesystem::path构造函数。

问题来了:尽管我们可以合法地(通过reinterpret_cast)将任何指针转换为const char*,但我们不能向后做:from const char*到eg const char8_t*(这会破坏严格的别名规则)。因此,如果我们有一些外部API返回char文件名的基于UTF-8的表示形式(例如,使用C语言编写的库),则无法安全地将指针转换为char8_t基于文件的指针。

那么,我们应该如何将这种char基于UTF-8字符串char8_t的视图转换为基于它们的UTF-8字符串?

c++ unicode utf-8 c++20

7
推荐指数
2
解决办法
217
查看次数

Windows 上的“C.UTF-8”C++ 语言环境?

我正在修复一个大型开源跨平台应用程序,以便它可以处理 Windows 上包含非 ANSI 字符的文件路径。


更新:

根据到目前为止我得到的答案和评论(谢谢!)我觉得我应该澄清一些观点:

  1. 无法修改几十个第三方库的代码来使用std::wchar_t。这不是一个选择。该解决方案必须与普通的 ol'等一起std::fopen()使用。std::ifstream

  2. 我在下面概述的解决方案的运行率为 99%,至少在我正在开发的系统上(Windows 10 版本 1909,内部版本 18363.535)。我还没有在任何其他系统上进行过测试。

    唯一剩下的问题,至少在我的系统上,基本上是数字格式,我希望替换方面std::numpunct能够解决问题(但我还没有成功)。


我当前的解决方案包括:

  1. 将 Windows 上的类别的C 区域设置设置为.UTF-8LC_CTYPE所有其他类别均设置为C应用程序所需的区域设置):

    // Required by the application.
    std::setlocale(LC_ALL, "C");
    
    // On Windows, we want std::fopen() and other functions dealing with strings
    // and file paths to accept narrow-character strings encoded in UTF-8.
    #ifdef _WIN32
    {
    #ifndef NDEBUG
        char* new_ctype_locale =
    #endif
            std::setlocale(LC_CTYPE, …
    Run Code Online (Sandbox Code Playgroud)

c++ windows boost locale boost-filesystem

6
推荐指数
1
解决办法
9623
查看次数

Windows代码页与标准C/C++文件名的交互?

客户抱怨我们的代码用于在文件名中写入带有日文字符的文件,但在所有情况下都不再有效.我们总是使用好的旧char*字符串来表示文件名,所以它对我来说有点震撼它曾经有效,我们没有做任何我知道应该让它停止工作的事情.我让他们发给我一个带有嵌入式文件名的文件,从我们的软件导出它,看起来字符串使用十六进制字符82和83作为双字节序列的第一个字符来表示日文字符.在线浏览让我相信这可能是SHIFT_JIS和/或Windows代码页932.

在我看来,之前发生的事情是fopen和ofstream ::使用此代码页打开接受的文件名; 现在只有fopen呢.我已经检查了Visual Studio fopen docs,我没有看到什么使得可接受的字符串传递给fopen.

从短期来看,我希望有人可以为我提供一些特定的Windows fopen与ofstream :: open问题.从长远来看,我真的想知道在Windows,Linux和OS X上用C++打开Unicode(和其他?)文件名的可接受方式.

编辑添加:我相信打开工作是在"C"语言环境中完成的,而那些不工作的打开是在客户的默认语言环境中完成的.然而,多年以来一直如此,该程序的旧版本今天仍然适用于他们的系统,所以这似乎是解释我们所看到的问题的一个远景.

更新:我向客户发送了一个小测试程序.它已经验证fopen与SHIFT_JIS文件名一起工作正常,而std :: ofstream则没有.这是在Visual Studio 2005中,无论我使用的是默认语言环境还是"C"语言环境,都会发生这种情况.

我仍然感兴趣,如果有人对此行为有解释(以及为什么它神秘地改变了 - 也许是VS2005的服务包?)并希望整合一个全面的"最佳实践"来处理便携式C++代码中的Unicode文件名.

c c++ filenames character-encoding

5
推荐指数
1
解决办法
4911
查看次数

C++ ifstream long full path无法正常工作

我想从磁盘读取文件,在程序执行期间使用QDialog(Qt Widget)我选择文件的路径.一段代码很简单:

ifstream infile(path.c_str());

if (infile.is_open()) {
    //some code   
}
else
    //log it
Run Code Online (Sandbox Code Playgroud)

问题出现取决于目标文件的位置:

  • 如果文件的路径是"D:\ folder\file" - 它会读取文件,一切正常
  • 如果文件的路径是"C:\ Users \RafałSurname\ Desktop\folder\file" - 文件无法打开

怎么解决这个问题?

c++ qt

0
推荐指数
1
解决办法
2861
查看次数