C ++,使用路径

时间:2016-10-28 13:21:10

标签: c++ file unicode io

有没有办法在c ++中使用环境变量来获取文件路径? 想法是在不花费的情况下使用它们,所以当我想保存/读取文件时,我不需要使用wchar来获得具有unicode标准的语言。

// EDIT

很少编辑,有更多解释。

所以我尝试实现的是读取/写入文件而不必担心路径中的字符。所以我不想使用wchar作为路径,但如果路径包含一些宽字符,它应该可以工作。

getenvGetEnvironmentVariable个功能,但他们需要在Windows设置Language for non-Unicode programs中设置适当的语言(Constrol Panel - > Clock, Language, and Region - > Region and Language - > Administrative)需要用户采取某些操作,这是我尽量避免的。

2 个答案:

答案 0 :(得分:1)

  

有函数getenv和GetEnvironmentVariable,但是他们需要在Windows设置中为非Unicode程序设置适当的语言

这特别是Windows问题。

在Linux等其他平台上,文件路径和环境变量本身是基于字节的;您可以使用标准C库函数访问它们,这些函数采用fopen()getenv()等字节串路径。路径名可以表示用户的Unicode字符串(使用某些编码解码,几乎总是UTF-8可以编码任何字符),但是对于代码,它们只是字节字符串。

另一方面,Windows具有文件名和环境变量,这些变量本身是16位(UTF-16)代码单元的字符串(与Unicode字符代码点几乎相同,但不完全相同,因为那会太容易了......但那是另一次的悲伤)。您可以使用UTF-16代码单元字符串(CreateFileW()在Windows上编译时)调用GetEnvironmentVariableW()wchar_t等Win32文件处理API,并直接访问任何文件名。

还有一些老式的基于字节的传统Win32函数,如GetEnvironmentVariableA()(如果您正在编译非Unicode项目,那么GetEnvironmentVariable()指的是这些函数)。如果您调用这些函数,Windows必须使用某些编码将您提供的char字节字符串转换为UTF-16字符串。 该编码是'ANSI'('A')特定于语言环境的默认代码页,这是“非Unicode程序的语言”设置。

虽然用户可以更改该编码,但不能将其设置为UTF-8或支持所有字符的任何其他编码,因此即使您要求用户更改它,仍然不会; t让您访问所有文件。因此,总是要避免使用Win32 A API。

当您希望以适用于Windows和其他平台的方式访问文件时,会出现问题。如果使用字节字符串调用C标准库,则Microsoft C运行时库会调整这些调用以调用基于字节的Win32 A API,如上所述,这些API非常有限。

所以你没有吸引力的选择是:

  1. 在代码中使用wchar_tstd::wstring字符串,仅使用Win32 API与文件名和环境变量进行交互,并接受您的代码永远不会在其他平台上运行,或者;
  2. 使用char和UTF-8编码的std::string字符串,放弃使用Windows上的非ASCII字符访问文件名和环境变量的代码,或者;
  3. 编写一个分支#ifdef代码的负载,以便在使用C标准函数进行文件名和环境交互之间切换,或者使用带有一堆UTF-8的Win32 API - char - to - {{1两者之间的字符串转换,以便代码可以跨多个平台工作,或者;
  4. 使用封装(3)的库。
  5. 这完全不是微软的错:Windows NT是在UTF-8或星界飞机发明之前的Unicode早期设计的,当时认为16位代码单元字符串是一种完全合理的方式来存储文本,而不是像我们现在所知的那种可悲的灾难。然而,令人遗憾的是,Windows从那时起就没有更新过,将UTF-8视为一流的公民,并提供了编写跨平台应用程序的简便方法。

答案 1 :(得分:0)

标准库为您提供 getenv 功能。这是一个例子:

#include <cstdlib>

int main()
{
    char* pPath;
    pPath = getenv("PATH");
    if (pPath)
        std::cout << "Path =" << pPath << std::endl;
    return 0;
}