Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   LoadFromFile y la letra "Ñ" (https://www.clubdelphi.com/foros/showthread.php?t=37802)

Flecha 23-11-2006 12:18:01

LoadFromFile y la letra "Ñ"
 
Tengo un pequeño problema.
Para unos procesos de carga de archivos de texto plano estoy utilizando un TStringList para leer en él el contenido del fichero. Para ello hago uso de su método LoadFromFile.
Pero resulta que la letra "Ñ" me la lee como "Ã`" con los correspondientes problemas que luego eso me origina. No sólo son distintos caracteres sino que son 2 en vez de 1 y me desplaza un espacio el resto de datos de la misma fila.

Para solucionarlo sólo se me ocurre olvidarme del LoadFromFile y cargar sobre el TStringList a base de Add() y de acceder al fichero con una variable TextFile leyéndolo fila a fila. Algo demasiado arcaico para los días en los que estamos, la verdad.

Por favor ¿Alguien tiene una idea mejor? :(

Flecha 23-11-2006 12:32:40

La cosa es peor de lo que creía.
Hacer uso de un TextFile y leerme el fichero de texto línea a línea tampoco me soluciona el problema.

Así que no tengo manera de leer un archivo de texto plano sin que me cambie la "Ñ" por "ô".

Ayuda please...:(

seoane 23-11-2006 12:56:14

Tu problema es que ese texto no lo guardaste desde un TStringList ¿a que no?, lo guardaste desde un programa que trabaja con la codificación UTF-8. En esta codificación la letra ñ se guarda como 2 bytes ($C3 $91), que se corresponden con "Ñ", por eso el TStringList lo lee así. La solución pasa por convertir el UTF-8 a texto ASCII, o decirle al otro programa, si puedes, que no utilice UTF-8

Flecha 23-11-2006 13:17:02

Gracias, pero no me vale porque el archivo no se crea desde ninguno de mis programas. Se crean desde otras empresas con sus propios programas, y que nos lo mandan a nosotros.

He comprobado que el formato en el que me llega el archivo es UTF-8, pero mi problema está en poder leer el contenido del fichero independientemente del formato en el que me llegue.

Hay quien me aconseja utilizar el TRichEdit para leer el archivo. Estoy probando.

¿Alguna opinión al respecto?

dec 23-11-2006 13:36:29

Hola,

Acabo de probar con algo así y parece ir bien:

Código Delphi [-]
var
  t: TStrings;
begin
  t := TStringList.Create;
  try
    // pruebas.txt está codificado con "UTF-8"
    t.LoadFromFile('C:\pruebas.txt');
    ShowMessage(UTF8Decode(t.Strings[0]));
  finally
    t.Free;
  end;
end;

También podría valer utilizando "Utf8ToAnsi" en lugar de "UTF8Decode", pero... se supone aquí que tratamos con un archivo codificado en "UTF-8"... si el mismo no estuviera codificado así nos encontraríamos con problemas también...

Desde luego en Google aparece información sobre lo que nos ocupa. Esta página de Delphi Fundamentals tal vez ayude algo...

dec 23-11-2006 13:48:13

Hola,

Acabo de recordar a los componentes SynEdit. Estos cuentan con una variante preparada para trabajar con archivos UTF-8. Se trata de UnicodeSynEdit. Estos componentes cuentan con un "SynEditMemo" que acaso podría serte de utilidad... Son unos componentes de código abierto y gratuitos, por cierto.

seoane 23-11-2006 13:51:56

:o :( :D Jajaja, yo como siempre reinventando la rueda.

Llevo como 10 minutos para hacer esto:


EDITO: Leer el código que pongo mas abajo, el que estaba aquí no era correcto

:D Y viene aquí David y me cuenta que existe la función UTF8Decode, jajajaja

dec 23-11-2006 13:56:47

Hola,

Pero no está demás saberlo hacer como tú lo sabes hacer Domingo. De hecho yo utilizo Delphi 7 y me huelo que la función susomentada no está disponible en versiones anteriores de Delphi. :)

Flecha 23-11-2006 14:43:56

Muchísimas gracias a los dos. ;)

Por cierto, mi programa está hecho en Delphi 5 así que, efectivamente, UTF8Decode y UTF8ToAnsi no las tengo disponibles. :o

He probado el curradísimo procedimiento de seoane, y no tengo buenas noticias. El programa se queda tonto cuando se ejecuta la línea
Código Delphi [-]
Result:= WideString(Str);

De todos modos, y como comenta dec, ¿funcionaría tambien si el formato del archivo no es UTF8?
¿Hay alguna forma de saber qué formato tiene el archivo antes de cargarlo para así saber exactamente con qué procedimiento leer sus datos?

seoane 23-11-2006 15:00:32

Prueba con esto:
Código Delphi [-]
function LoadUTF8FromFile(Filename: string): WideString;
var
  Stream: TMemoryStream;
  Size: Integer;
  Str: PWChar;
begin
  Result:= '';
  Stream:= TMemoryStream.Create;
  try
    Stream.LoadFromFile(Filename);
    Size:= MultiByteToWideChar(CP_UTF8,0,Stream.Memory,
      Stream.Size,nil,0);
    if Size > 0 then
    begin
      GetMem(Str,(Size+1)*Sizeof(WideChar));
      FillChar(Str^,(Size+1)*Sizeof(WideChar),#0);
      try
        if MultiByteToWideChar(CP_UTF8,0,Stream.Memory,
           Stream.Size,Str,Size) > 0 then
        begin
          Result:= WideString(Str);
        end;
      finally
        FreeMem(Str);
      end;
    end;
  finally
    Stream.Free;
  end;
end;

marcoszorrilla 11-06-2007 16:35:24

Yo he estado haciendo unas pruebas de la siguiente manera

En un fichero Ms-Dos pongo distintos textos, con eñes, acentos etc,. lo cargo a un memo:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Lines.LoadFromFile('E:\Pruebas\Fichero.txt');
end;

procedure TForm1.Button2Click(Sender: TObject);
var
s:Pchar;
begin
OemToChar(PChar(Memo1.Lines[2]),PChar(s));
ShowMessage(s);
end;

Y luego con la función OemToChar me lo convierte perfectamente, el ejemplo es muy simple pero no tengo tiempo para más.

Un Saludo.

seoane 11-06-2007 16:54:08

Creo que el caso que describes marcos es diferente, en tu caso el problema es que el archivo utiliza un juego de caracteres diferente al que usa windows, mientras que, segun lo entiendo yo, el problema en en este caso es que se utiliza una codificacion diferente.

De todas formas, esto ¿seguro que te funciona? :confused: :
Código Delphi [-]
procedure TForm1.Button2Click(Sender: TObject);
var
s:Pchar;
begin
OemToChar(PChar(Memo1.Lines[2]),PChar(s));
ShowMessage(s);
end;
Porque ahí s esta apuntando a una posición de memoria aleatoria, no a ningún buffer, al menos eso me parece a mi.

Flecha 19-06-2007 10:35:01

Gracias de nuevo a todos.
Al final decidí cortar por lo sano.
Yo necesitaba un sistema lector "universal" de archivos de texto. De forma que independientemente del formato en que fuese creado el archivo de texto (ASCI, UTF8, etc), yo pudiera leer el contenido sin que hubiese varianción en los caracteres.
Pero como no había manera de lograrlo decidí exigir a la empresa que nos manda los archivos de texto, que nos los mande en el formato correcto.


La franja horaria es GMT +2. Ahora son las 20:54:10.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi