Pregunta

Medio Ambiente: GCC / G ++ Linux

Tengo un archivo no ASCII en el sistema de archivos y voy a abrirlo.

Ahora tengo un wchar_t *, pero no sé cómo abrirlo. (Mi FOPEN de confianza sólo se abre el archivo char *)

Por favor, ayuda. Muchas gracias.

¿Fue útil?

Solución

Hay dos respuestas posibles:

Si desea asegurarse de que todos los nombres de archivo Unicode son representables, se puede codificar el supuesto de que los usos del sistema de archivos UTF-8 nombres de archivo. Este es el enfoque de Linux de escritorio aplicación "moderna". Sólo convertir sus cadenas de wchar_t (UTF-32) a UTF-8 con funciones de biblioteca (iconv funcionaría bien) o su propia aplicación (pero las operaciones de búsqueda de las especificaciones para que no lo consigue muy mal como lo hizo Shelwien), a continuación, utilizar fopen .

Si usted quiere hacer las cosas de los estándares más orientadas manera, se debe utilizar wcsrtombs para convertir la cadena wchar_t en una cadena multibyte char en la codificación local (que es de esperar es UTF-8 de todos modos en cualquier sistema moderno) y el uso fopen . Tenga en cuenta que esto requiere que establezca previamente la configuración regional con setlocale(LC_CTYPE, "") o setlocale(LC_ALL, "").

Y, por último, no es exactamente una respuesta sino una recomendación:

Almacenamiento de nombres de archivo como cadenas wchar_t es probablemente un error horrible. En su lugar, debe almacenar los nombres de archivo como cadenas de datos abstractos, y sólo convertirlas a wchar_t justo a tiempo para su visualización en la interfaz de usuario (si es incluso necesario para que, muchos kits de herramientas de interfaz de usuario utilizan cadenas de bytes de civil sí mismos y hacer la interpretación como caracteres para ti). De esta manera se elimina una gran cantidad de posibles casos de esquina desagradables, y nunca se encuentra con una situación donde algunos archivos son inaccesibles debido a sus nombres.

Otros consejos

Linux no es UTF-8, pero es su única opción para los nombres de archivo de todos modos

(Los archivos pueden tener lo que quieras dentro de a.)


Con respecto a los nombres de archivo, Linux no tiene realmente una serie de codificación de qué preocuparse. Los nombres de archivo son cadenas de bytes que deben ser terminada en nulo.

Esto no significa precisamente que Linux es UTF-8, pero sí quiere decir que no es compatible con caracteres de ancho, ya que podría tener un cero en un byte que no es el byte final.

Pero UTF-8 preserva el modelo no-nulos, excepto-en-el-final, así que tengo que creer que el enfoque práctico es "convertir a UTF-8" para nombres de archivo.

El contenido de los archivos es una cuestión de normas sobre el nivel del núcleo de Linux, por lo que aquí no hay nada de Linux-y que pueda o quiera hacer. El contenido de los archivos será exclusivamente la preocupación de los programas que leen y escriben ellos. Linux sólo almacena y devuelve el flujo de bytes, y puede tener todas las NULs que desee.

string Convertir wchar a cadena UTF-8 char, a continuación, utilizar fopen.

typedef unsigned int   uint;
typedef unsigned short word;
typedef unsigned char  byte;

int UTF16to8( wchar_t* w, char* s ) {
  uint  c;
  word* p = (word*)w;
  byte* q = (byte*)s; byte* q0 = q;
  while( 1 ) {
    c = *p++;
    if( c==0 ) break;
    if( c<0x080 ) *q++ = c; else 
      if( c<0x800 ) *q++ = 0xC0+(c>>6), *q++ = 0x80+(c&63); else 
        *q++ = 0xE0+(c>>12), *q++ = 0x80+((c>>6)&63), *q++ = 0x80+(c&63);
  }
  *q = 0;
  return q-q0;
}

int UTF8to16( char* s, wchar_t* w ) {
  uint  cache,wait,c;
  byte* p = (byte*)s;
  word* q = (word*)w; word* q0 = q;
  while(1) {
    c = *p++;
    if( c==0 ) break;
    if( c<0x80 ) cache=c,wait=0; else
      if( (c>=0xC0) && (c<=0xE0) ) cache=c&31,wait=1; else 
        if( (c>=0xE0) ) cache=c&15,wait=2; else
          if( wait ) (cache<<=6)+=c&63,wait--;
    if( wait==0 ) *q++=cache;
  }
  *q = 0;
  return q-q0;
}

Salida este documento

http://www.firstobject.com/wchar_t- cadena-en-linux-osx-windows.htm

Creo que Linux sigue estándar POSIX, que trata a todos los nombres de archivo como UTF-8.

Lo tomo que es el nombre del archivo que contiene caracteres no ASCII, no el propio archivo, cuando se dice "archivo no ASCII en el sistema de archivos". Realmente no importa lo que el archivo contiene.

Se puede hacer esto con fopen normal, pero que tendrá que coincidir con la codificación de los usos del sistema de archivos.

Depende de qué versión de Linux y qué sistema de archivos que está utilizando y cómo se ha configurado, pero es probable que, si se tiene suerte, los usos del sistema de archivos UTF-8. Así que tómese su wchar_t (que es probablemente una cadena codificada en UTF-16?), Convertirlo a un char string codificado en UTF-8, y pasar a que FOPEN.

// locals
string file_to_read;           // any file
wstring file;                  // read ascii or non-ascii file here 
FILE *stream;
int read = 0;    
wchar_t buffer= '0';

if( fopen_s( &stream, file_to_read.c_str(), "r+b" ) == 0 )   // in binary mode
  {      
      while( !feof( stream ))
      { 
     // if ascii file second arg must be sizeof(char). if non ascii file sizeof( wchar_t)
        read = fread( & buffer, sizeof( char ), 1, stream );  
        file.append(1, buffer);
      }
  }

file.pop_back(); // since this code reads the last character twice.Throw the last one
fclose(stream);

// and the file is in wstring format.You can use it in any C++ wstring operation
// this code is fast enough i think, at least in my practice
// for windows because of fopen_s
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top