PDA

Ver la Versión Completa : Unas cuantas cosas de archivos y hexadecimal.


alt126
02-10-2005, 11:01:17
Estoy haciendo un editor de ficheros de un juego bastante antiguo...PCFutbol 4.0, supongo que casi todos sabeis cual es.

Bueno, la cosa es que esta casi terminado pero tengo problemas al leer y escribir directamente codigo hexadecimal sobre un archivo.

Es decir, los archivos que leo y que escribo tienen codigo hexadecimal, pero estan en modo texto. Entonces para leerlos lo que hago es leer de un archivo un caracter y guardarlo en una variable (int), con lo que ya tengo su codigo hexadecimal asociado. Espero explicarme bien. Por ejemplo:

Modo texto del archivo: Copyright (c)1995 Dinamic Multimedia....

Codigo hexadecimal asociado: 436F7079726967687420286329313939352044696E616D6963204D756C74696D65646961

Bueno la cosa es que si hago eso...no me lee todo el archivo, encuentra algun caracter, que lo identifica como fin de archivo, con lo que termina antes de tiempo...¿?¿?¿?...alguna idea de como arreglar eso?

Despues, a la hora de escribir, al pasar de hexadecimal a cadena y pasarla al archivo...me sucede que al escribir este par hexadecimal "0A"...que corresponde al caracter '\n', o en formato entero 10...en vez de ponerme 1 caracter (como seria lo logico), me pone 2...es decir...escribe en el archivo..."0D0A"...con lo que me tiene loco!!

Y ya por ultimo, pregunta tonta pero bueno...las imagenes del juego estan almacenadas en archivos con extension dfg...parece ser que es algun tipo de bmp, pero modificado...alguien sabria como poder editarlo??

Gracias por todo

Un saludo

Antonio

marcoszorrilla
02-10-2005, 12:52:04
Bueno en cuanto al retorno de carro es habitual que vaya acompañado por una alimentación de línea por eso siempre van juntos los dos códigos
0A ----- Line Feed (Alimentación de línea)
0D ----- Carriage Return (Retorno de carro()
De hecho la tecla enter produce esos códigos precisamente.

Puedes probarlo:
Esto es una prueba <Enter>
Guardálo con el nombre que desees por ejemplo prueba:
vete al DOS
Debug prueba
D <enter>
Y ahora veras en hexadecimal todo lo escrito y al final 0AOD

Para abandonar deBug pulsa Q y luego Enter

En cuanto al otro problema porque no lees el archivo entero y no caracter a caracter lo guardas en una variable o donde creas oportuno y luego vas tomando de 2 en 2 los códigos y los pasas a decimal o a lo que corresponda.

Un Saludo.

alt126
02-10-2005, 21:39:51
Y como cargo un archivo entero en una cadena???

pq yo lo que hago es abrir el archivo (fopen), ir copiando con (fget o fgets), y luego cerrar el archivo (fclose).

Gracias

Un saludo

Antonio

dec
03-10-2005, 07:05:13
Hola,


Y como cargo un archivo entero en una cadena???

Se me ocurren estas dos maneras: no dudo que existan otras mejores.



void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString archivo = "C:\\archivo.txt";
TStringList *temporal = new TStringList();
try
{
temporal->LoadFromFile(archivo);
ShowMessage(temporal->Text);
}
__finally
{
temporal->Free();
}
}



void __fastcall TForm1::Button2Click(TObject *Sender)
{
AnsiString archivo = "C:\\archivo.txt";
TFileStream *fs = new TFileStream(archivo, fmOpenRead);
TStringStream *ss = new TStringStream("");
try
{
ss->CopyFrom(fs, 0);
ShowMessage(ss->DataString);
}
__finally
{
fs->Free();
ss->Free();
}
}

ppb
03-10-2005, 14:13:35
Aunque no entiendo muy bien lo que te pasa , para no tener
problemas con los retorno de carro ( 0D0A ) maneja el fichero
en modo binario no en modo texto.

alt126
03-10-2005, 16:08:17
Pues va a ser que no....

...vamos a ver he probado lo de cargar el archivo de una vez con el Tstringlist, pero nada...

el archivo es este: archivo (http://www.geocities.com/antonio_garcia_web/1.doc)

Lo he puesto con extension .doc para poder subirlo. Si lo habris con un editor hexadecimal, podreis verlo perfectamente. Yo lo que quiero es obtener en una cadena todo el codigo hexadecimal. Porque hasta ahora para poder trabajar con el, lo que tengo que hacer es abrir el archivo con un editor hexadecimal, seleccionar todo el codigo y copiarlo a un archivo de texto.

La version hexadecimal de ese archivo es: archivohex (http://www.geocities.com/antonio_garcia_web/2.doc)

Asi que si alguien pudiera decirme como leer directamente el archivo y obtener ese codigo hexadecimal en una cadena y luego volver a pasarlo a otro archivo....

Muchas Gracias

Un saludo

Antonio

marcoszorrilla
03-10-2005, 23:16:01
He preparado este ejemplo, que puede servir como base, como es tarde lo dejo así, solo queda darle algunos retoques:

Se necesita:
Un TOpenDialog y un StringGrid


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids;

type
TForm1 = class(TForm)
Button1: TButton;
OpenDialog1: TOpenDialog;
StringGrid1: TStringGrid;

procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}



procedure TForm1.Button1Click(Sender: TObject);
var
iFileHandle: Integer;
iFileLength: Integer;
iBytesRead: Integer;
Buffer: PChar;
i: Integer;
j: Integer;
begin
if OpenDialog1.Execute then
begin
try
iFileHandle := FileOpen(OpenDialog1.FileName, fmOpenRead);
iFileLength := FileSeek(iFileHandle,0,2);
FileSeek(iFileHandle,0,0);
Buffer := PChar(AllocMem(iFileLength + 1));
iBytesRead := FileRead(iFileHandle, Buffer^, iFileLength);

FileClose(iFileHandle);
for i := 0 to iBytesRead-1 do
begin
StringGrid1.RowCount := StringGrid1.RowCount + 1;

StringGrid1.Cells[1,i+1] := Buffer[i];
StringGrid1.Cells[2,i+1] := IntToHex(integer(Buffer[i]),2);
end;
finally
FreeMem(Buffer);
end;
end;

end;

end.



Un Saludo

alt126
04-10-2005, 22:14:38
he probado ese codigo, cambiado al c++ y funciona pero mirad lo que pasa:

Principio de la cadena, copiada de un editor hexadecimal
436F7079726967687420286329313939352044696E616D6963204D756C74696D65646961002090010...

Principio de la cadena, obtenida mediante el codigo anterior:
436F7079726967687420286329313939352044696E616D6963204D756C74696D656469610020FFFFFF90010

El principio es el mismo...ok...pero mirad las FFFFF...esta el archivo plagado de ellas...y no tienen porque salir, porque leyendo caracter a caracter no salen...

..alguien entiende algo?...ademas no puedo quitar todas las F, pq quitar algunas que si valen.

Pd.- pprey, no he podido probar tu codigo, pq no se como hacer un pas y usarlo en c++. Si pudieras pasarlo a c++..

Gracias a todos

Un saludo

Antonio

pprey
05-10-2005, 13:55:14
Con respecto a pasartelo a C++ lo que te envie, ahora mismo no podría pasartelo a C++ porque no tengo mucho tiempo para ello. Por lo que veo ahora tienes problemas con las FFFF con el codigo que te paso otro compañero. Pues bien creo que el problema de las FFFF es que al pasar tu el codigo a C desde delphi, quizás tengas algun problema en los bucles. Mira bien tu codigo y los loops que haces, a ver si tienes algun problema con los indices.
Si tengo un momento y mi codigo te lo puedo pasar a C++, ya te lo enviaré o bien te mando un .pas para que lo incluyas en un paquete de buider.

alt126
05-10-2005, 14:15:10
El codigo que se puso traducido a c++ es mas o menos este:

if(odFichero->Execute())
{
equipo = odFichero->FileName;
iFileHandle = FileOpen(odFichero->FileName, fmOpenRead);
iFileLength = FileSeek(iFileHandle,0,2);
FileSeek(iFileHandle,0,0);
Buffer = PChar(AllocMem(iFileLength + 1));
iBytesRead = FileRead(iFileHandle, Buffer, iFileLength);
FileClose(iFileHandle);
for(int i=0;i < iBytesRead-1;i++)
{
cadenahex = cadenahex + IntToHex((int)(Buffer[i]),2);
}
}

alt126
05-10-2005, 17:49:19
bueno, al final he conseguido que funcione...he comprobado que las FFFF esas, las ponia pq el numero que habia en buffer era negativo y al pasarlo a hexadecimal pues ponia unas cuantas FFFF y luego el par correcto. Asi que cuando el numero es negativo quito las Fs...y funciona perfect...

...Asi que la primera parte...prueba SUPERADA!!!...gracias a todos...

ahora vamos con la segunda parte...ahora es al contrario...tenemos nuestra cadena hexadecimal...y hay que pasarla a un archivo de texto normal...lo hago y lo hace todo perfectamente peroooooooooo...como ya os conte, cuando encuentra el codigo hexadecimal 0A, intenta escribir un caracter que en el archivo aparece como 2 caracteres...es decir en vez de escribir en el archivo 0A escribe 0D0A.

La prueba es que he intentado a escribir en un archivo un 10 y tachan...me hace lo mismo...0D0A.

Es decir tan simple como esto:


archivo=fopen("1.txt","w");
fputc(10,archivo);
fclose(archivo);

si miramos el resultado con un editor hexadecimal en vez de ser 0A como deberia es 0A0D...

Alguna manera de como hacer que me escriba solo 0A????

Gracias

Un saludo

Antonio