代码之家  ›  专栏  ›  技术社区  ›  Vincent Robert

_Mac OS X下的wfopen等价物

  •  16
  • Vincent Robert  · 技术社区  · 18 年前

    我要找的是相当于Windows的 _wfopen()

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

    5 回复  |  直到 17 年前
        1
  •  14
  •   Vincent Robert    17 年前

    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");
    

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

        2
  •  5
  •   Chris Hanson    18 年前

    您只想使用可能包含Unicode字符的路径打开文件句柄,对吗?把这条路过去就行了 文件系统表示 fopen

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

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

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

    例如,他们需要决定是否将“”存储为一个或两个代码单元(或者 LATIN SMALL LETTER E WITH ACUTE LATIN SMALL LETTER E 然后 COMBINING ACUTE ACCENT )。这将导致两个不同长度的字节序列,Mac OS X和Windows都可以避免将多个同名文件(用户可以感觉到)放在同一目录中。

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

        3
  •  2
  •   Mecki    17 年前

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

    看见 here . 引述:

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

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

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

        4
  •  0
  •   Greg Hurlman    18 年前

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

    你可以用UTF-8字符串来调用FOpenE,不管语言是什么,都不能帮助OSX上的C++。

        5
  •  0
  •   AVG    12 年前

    我已通过读取配置UTF8文件中的文件名 wifstream wchar\t 缓冲区)。

    wifstream从文件中读取每个字节,以在缓冲区中分离wchar\u t单元。所以我们有3个空字节,虽然 烧焦 一串因此程序员可以使用 wcstombs 函数将宽字符串转换为多字节字符串。

    API支持UTF8。为了更好地理解您的文件,请使用内存监视器和十六进制编辑器。