Pregunta

Estoy buscando el equivalente de Windows. _wfopen() en Mac OS X.¿Alguna idea?

Necesito esto para portar una biblioteca de Windows que usa wchar* para su interfaz de Archivo.Como se pretende que sea una biblioteca multiplataforma, no puedo confiar en cómo la aplicación cliente obtendrá la ruta del archivo y se la dará a la biblioteca.

¿Fue útil?

Solución

La API POSIX en Mac OS X se puede utilizar con cadenas UTF-8.Para convertir una cadena wchar_t a UTF-8, es posible utilizar el marco CoreFoundation de Mac OS X.

Aquí hay una clase que envolverá una cadena generada en UTF-8 a partir de una cadena wchar_t.

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;
};

Uso:

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

Esto funcionará para leer o escribir archivos.

Otros consejos

Solo desea abrir un identificador de archivo usando una ruta que pueda contener caracteres Unicode, ¿verdad?Simplemente pasa el camino en representación del sistema de archivos a fopen.

  • Si la ruta proviene de los marcos estándar de Mac OS X (por ejemplo, un panel abierto, ya sea Carbon o Cocoa), no necesitará realizar ninguna conversión y podrá usarlo tal como está.

  • Si está generando parte de la ruta usted mismo, debe crear un CFStringRef a partir de su ruta y luego obtenerlo en la representación del sistema de archivos para pasarlo a las API POSIX como open o fopen.

En términos generales, no tendrás que hacer mucho de eso para la mayoría de las aplicaciones.Por ejemplo, muchas aplicaciones pueden tener archivos de datos auxiliares almacenados en el directorio de soporte de aplicaciones del usuario, pero siempre que los nombres de esos archivos sean ASCII y utilice las API estándar de Mac OS X para ubicar el directorio de soporte de aplicaciones del usuario, no necesita hacer un montón de conversiones paranoicas de un camino construido con esos dos componentes.

Editado para agregar: Yo advertiría fuertemente contra convertir arbitrariamente todo a UTF-8 usando algo como wcstombs porque la codificación del sistema de archivos no es necesariamente idéntica al UTF-8 generado.Tanto Mac OS X como Windows utilizan reglas de descomposición canónica específicas (pero diferentes) para la codificación utilizada en las rutas del sistema de archivos.

Por ejemplo, deben decidir si "é" se almacenará como una o dos unidades de código (ya sea LATIN SMALL LETTER E WITH ACUTE o LATIN SMALL LETTER E seguido por COMBINING ACUTE ACCENT).Esto dará como resultado dos secuencias de bytes diferentes (y de diferente longitud), y tanto Mac OS X como Windows trabajan para evitar colocar múltiples archivos con el mismo nombre (como los percibe el usuario) en el mismo directorio.

Las reglas sobre cómo realizar esta descomposición canónica pueden volverse bastante complicadas, por lo que en lugar de intentar implementarla usted mismo, es mejor dejar que las funciones que los marcos del sistema le han proporcionado hagan el trabajo pesado.

@JKP:

No todas las funciones en MacOS X aceptan UTF8, pero los nombres de archivos y las rutas de archivo pueden ser UTF8, por lo que todas las funciones POSIX relacionadas con el acceso a archivos (open, fopen, stat, etc.) aceptan UTF8.

Ver aquí.Cita:

Cómo se ve un nombre de archivo al nivel de la API depende de la API.API de carbono actual Los nombres de archivo como una matriz de caracteres UTF-16;Los Posix los manejan como una variedad de UTF-8, por lo que UTF-8 funciona bien en la terminal.La forma en que se almacena en el disco depende del formato de disco;HFS+ usa UTF-16, pero eso no es importante en la mayoría de los casos.

Algunas otras funciones POSIX también manejan UTF8.P.ej.las funciones que tratan con nombres de usuario, nombres de grupos o contraseñas de usuario usan UTF8 para almacenar la información (por lo tanto, un nombre de usuario puede ser japonés y su contraseña puede ser china, no hay problema).

Pero no todos manejan UTF8.P.ej.para todas las funciones de cadena, una cadena UTF8 es simplemente una cadena C normal y los caracteres superiores a 126 no tienen un significado especial.No entienden el concepto de múltiples bytes (caracteres en C) que forman un único carácter Unicode.La forma en que otras API manejan el puntero char * que se les pasa es diferente de una API a otra.Sin embargo, como regla general se puede decir:

La función solo acepta cadenas C con caracteres ASCII puros (solo en el rango de 0 a 126) o aceptará UTF8.Por lo general, las funciones no permiten caracteres superiores a 126 y los interpretan en cualquier otra codificación que no sea UTF8.Si este realmente fuera el caso, está documentado y luego debe haber una manera de pasar la codificación junto con la cadena.

Si estás usando Cocoa, es bastante fácil con NSString.Simplemente cargue los datos UTF16 usando -initWithBytes:length:encoding:(o quizás -initWithCString:encoding:) y luego obtenga una versión UTF8 llamando a UTF8String en el resultado.Luego, simplemente llame a fopen con su nueva cadena UTF8 como parámetro.

Definitivamente puedes llamar a fopen con una cadena UTF-8, independientemente del idioma; aunque no puedo ayudar con C++ en OSX, lo siento.

He leído el nombre del archivo desde el archivo de configuración UTF8 hasta wifstream (usa wchar_t buffer).

La implementación de Mac es diferente a la de Linux y Windows.wifstream lee cada byte del archivo para separar la celda wchar_t en el búfer.Entonces tenemos 3 bytes vacíos, aunque abierto requiere carbonizarse cadena.Así el programador puede utilizar tumbas función para convertir una cadena de caracteres ancha en una cadena de varios bytes.

La API admite UTF8.Para una mejor comprensión, utilice el observador de memoria y el editor hexadecimal para su archivo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top