C++ _Mac OS X下的wfopen等价物

C++ _Mac OS X下的wfopen等价物,c++,winapi,macos,porting,fopen,C++,Winapi,Macos,Porting,Fopen,我正在寻找Mac OS X下的Windows。有什么想法吗 我需要它来移植一个Windows库,该库使用wchar*作为其文件接口。由于这是一个跨平台库,我无法依赖客户端应用程序如何获取文件路径并将其提供给库。如果使用Cocoa,使用NSString相当简单。只需使用-initWithBytes:length:encoding:(或者-initWithCString:encoding:)加载UTF16数据,然后通过调用结果上的UTF8String获得UTF8版本。然后,用新的UTF8字符串作为参

我正在寻找Mac OS X下的Windows。有什么想法吗


我需要它来移植一个Windows库,该库使用
wchar*
作为其文件接口。由于这是一个跨平台库,我无法依赖客户端应用程序如何获取文件路径并将其提供给库。

如果使用Cocoa,使用NSString相当简单。只需使用-initWithBytes:length:encoding:(或者-initWithCString:encoding:)加载UTF16数据,然后通过调用结果上的UTF8String获得UTF8版本。然后,用新的UTF8字符串作为参数调用fopen


你可以用UTF-8字符串来调用fOpenD,不管语言是什么,都不能帮助C++在OSX上进行操作。-抱歉。

< p>你只想用一个包含Unicode字符的路径打开文件句柄,对吗?只需将文件系统表示中的路径传递到
fopen

  • 如果路径来自股票MacOSX框架(例如,一个开放式面板,无论是Carbon还是Cocoa),您将不需要对其进行任何转换,并且可以按原样使用它

  • 如果您自己正在生成路径的一部分,那么应该从您的路径创建一个CFStringRef,然后在文件系统表示中获得它,以传递给POSIX API,如
    open
    fopen

一般来说,对于大多数应用程序,您不需要做很多这方面的工作。例如,许多应用程序可能会在用户的应用程序支持目录中存储辅助数据文件,但只要这些文件的名称是ASCII,并且您使用标准Mac OS X API来定位用户的应用程序支持目录,您不需要对由这两个组件构建的路径进行大量的偏执转换

编辑添加:我强烈警告不要使用
wcstombs
之类的东西将所有内容任意转换为UTF-8,因为文件系统编码不一定与生成的UTF-8相同。Mac OS X和Windows都对文件系统路径中使用的编码使用特定(但不同)的规范分解规则

例如,他们需要决定是否将“é”存储为一个或两个代码单元(带锐音的
拉丁文小写字母E
拉丁文小写字母E
,后跟组合锐音的
)。这将导致两个不同长度的字节序列,Mac OS X和Windows都可以避免将多个同名文件(用户可以感觉到)放在同一目录中

如何执行此规范分解的规则可能会非常复杂,因此与其尝试自己实现它,最好将其留给系统框架为您提供的功能来完成繁重的工作。

@JKP:

并非MacOS X中的所有函数都接受UTF8,但文件名和文件路径可能是UTF8,因此所有处理文件访问(open、fopen、stat等)的POSIX函数都接受UTF8

看。引述:

文件名在API级别的外观 取决于API。当前碳 API将文件名处理为 UTF-16字符;POSIX单手柄 它们是UTF-8的一个数组 为什么UTF-8在终端中工作良好。怎么 它存储在磁盘上取决于 磁盘格式;HFS+使用UTF-16,但 在大多数情况下,这并不重要

其他一些POSIX函数也处理UTF8。例如,处理用户名、组名或用户密码的函数使用UTF8存储信息(因此,用户名可以是日语,密码可以是中文,没有问题)

但并不是所有的处理器都能处理UTF8。例如,对于所有字符串函数,UTF8字符串只是普通的C字符串,126以上的字符没有特殊意义。他们不理解多个字节(C中的字符)构成单个Unicode字符的概念。其他API处理传递给它们的char*指针的方式因API而异。然而,作为一条规则,你可以说:


该函数要么只接受带有纯ASCII字符的C字符串(仅在0到126之间),要么接受UTF8。通常函数不允许使用126以上的字符,并使用UTF8以外的任何其他编码对其进行解释。如果确实是这样的话,它会被记录下来,然后必须有一种方法将编码与字符串一起传递。

Mac OS X中的POSIX API可用于UTF-8字符串。为了将wchar_t字符串转换为UTF-8,可以使用Mac OS X中的CoreFoundation框架

下面是一个类,它将从wchar\u t字符串包装UTF-8生成的字符串

class Utf8
{
public:
    Utf8(const wchar_t* wsz): m_utf8(NULL)
    {
        // OS X uses 32-bit wchar
        const int bytes = wcslen(wsz) * sizeof(wchar_t);
        // comp_bLittleEndian is in the lib I use in order to detect PowerPC/Intel
        CFStringEncoding encoding = comp_bLittleEndian ? kCFStringEncodingUTF32LE
                                                       : kCFStringEncodingUTF32BE;
        CFStringRef str = CFStringCreateWithBytesNoCopy(NULL, 
                                                       (const UInt8*)wsz, bytes, 
                                                        encoding, false, 
                                                        kCFAllocatorNull
                                                        );

        const int bytesUtf8 = CFStringGetMaximumSizeOfFileSystemRepresentation(str);
        m_utf8 = new char[bytesUtf8];
        CFStringGetFileSystemRepresentation(str, m_utf8, bytesUtf8);
        CFRelease(str);
    }   

    ~Utf8() 
    { 
        if( m_utf8 )
        {
            delete[] m_utf8;
        }
    }

public:
    operator const char*() const { return m_utf8; }

private:
    char* m_utf8;
};
用法:

const wchar_t wsz = L"Here is some Unicode content: éà€œæ";
const Utf8 utf8 = wsz;
FILE* file = fopen(utf8, "r");

这将用于读取或写入文件。

我已通过wifstream从配置UTF8文件中读取文件名(它使用wchar\t缓冲区)

Mac实现不同于Linux和Windows。 wifstream从文件中读取每个字节,以在缓冲区中分离wchar\u t单元。因此我们有3个空字节,尽管open需要char字符串。因此,程序员可以使用wcstombs函数将宽字符串转换为多字节字符串


API支持UTF8。为了更好地理解使用内存观察器和十六进制编辑器,您的文件。< / P>我不使用COCOA和AM使用C++,而不是Objor。C如果您将一个UTF-8字符串提供给FOpen-(),我可以将UTF-16字符串转换成UTF-8,但是在Mac OS X上如何容易地(再次使用C/C++).这不是一个确定的答案,因为我依赖CFString而不是NSString,但基本思想是一样的。谢谢。如果delete是多余的,只需delete对于想在代码中尝试此功能的人,显示了两种编写“é”的方法(不同的字符代码)。在显示unicode的Linux文件管理器上,当通常不允许两个同名文件时,它们将显示为相等。例如,
touch$'file-\u00e9'$'file-\u0065\u0301'