Newsgroup: it.comp.lang.c
Titolo: Confronto 5 byte lette con fread

Ciao,
leggo i primi 5 byte di un file binario così:
gboolean DetectArchiveType ( gchar *path )
{
	FILE *dummy_ptr;
	unsigned char magic[4];
	dummy_ptr = g_fopen ( path , "rb" );
	if (dummy_ptr == NULL) return FALSE;
	if ( fread ( magic, 1, 5, dummy_ptr ) == 0 )
	{
		fclose( dummy_ptr);
		g_print ("An error occurred !\n");
		return FALSE;
	}
	fclose ( dummy_ptr );
50:	if ( magic == '\50\4b\03\04\0a' ) g_print ("You choosed a zip
archive !");
	return TRUE;
Ma oltre a beccarmi un warning comparison between pointer and integer
alla linea 50 ovviamente aprendo un file zip non stampa la stringa in
g_print. Come debbo mettere nella if i 5 byte che caratterizzano un
file zip ?
Colossus

 archive !");
Ok, debbo usare memcmp ma come ? Ottengo lo stesso warning 
ed ovviamente il confronto non funziona !
-- 
Colossus
Cpsed, a Linux OpenGL 3D scene editor
http://cpsed.sourceforge.net/


Leggi 5 byte e li memorizzi in un array lungo 4 caratteri ??
Dimensiona correttamente magic.
e poi puoi confrontare le sequenze di byte con memcmp() da string.h,
che ti invito ad andare a vedere. Comunque il punto essenziale e' che
che gli passi 2 puntatori e il numero N di byte da confrontare e 
restituisce 0 se e solo se i primi N byte puntati dai due puntatori
coincidono.
Quindi puoi scrivere:
if (0==memcmp(magic,"\50\4b\03\04\0a",5)) g_print(etcetcetc);
In ogni caso sappi che
1) In C le stringhe si delimitano con i doppia apici non con i singoli.
2) Per confrontare le stringhe (che sono sequenze di char terminate da
un valore 0) si usa la funzione strcmp() da string.h
3) In questo caso (non sapendo bene che magicnumber aspettarmi e cosa
leggo) meglio usare un confronto tra zone di memoria (per le quali
lo 0 non ha un significato particolare) piuttosto che stringhe.
4) Nel caso tu volessi usare magic come una stringa dovresti
dimensionarlo ad un carattere in piu' (quindi 6 char)
e mettere nell'ultima posizione uno zero per indicare la fine di magic.
magic[5]=0;
ciao,
g.

 if (0==memcmp(magic,"\50\4b\03\04\0a",5)) g_print(etcetcetc);
Purtroppo non funziona, non mi esegue la g_print; con un editor
esadecimale
ho visto la sequenza 50 4b 03 04 0a dei files .zip per cui sono sicuro
che è giusta, hai altre idee ?
Grazie per aver risposto,
Colossus

 che è giusta, hai altre idee ?
Prima di tutto non basta guardare alcuni files.
Guarda un po' qui (uno a caso trovato con google).
http://www.astro.keele.ac.uk/~rno/Computing/File_magic.html
Il magic number per .zip e' di 4 bytes (corrisponde a PK\03\04 )
Infatti il primo file .zip che ho provato ad aprire aveva
come quinto byte uno zero invece che \0a.
In genere negli zip il 5o byte codifica la versione del programma
necessaria ad aprire il file o qualcosa di simile.
ciao,
g.

 zero o no ??
Certo.
Quando dichiari un array quello che scrivi tra parentesi è il numero di
elementi, NON l'ultimo indice dell'array.
int a[4];
non significa che a ha 5 elementi che vanno da 0 a 4, ma che ne ha 4 che
vanno da 0 a 3.
In generale a[n] = {a[0],...,a[n-1]}
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 come quinto byte uno zero invece che \0a.
Ok, ho modificato il listato:
gboolean DetectArchiveType ( gchar *path )
{
	FILE *dummy_ptr;
	unsigned char magic[4];
	dummy_ptr = g_fopen ( path , "rb" );
	if (dummy_ptr == NULL) return FALSE;
	int br = fread ( magic, 1, 4, dummy_ptr );
	if ( br == 0 )
	{
		fclose( dummy_ptr);
		g_print ("An error occurred !\n");
		return FALSE;
	}
	fclose ( dummy_ptr );
	g_print ("Letti: %d memcmp: %d\n" , br,memcmp ( magic,"\50\4b\03\04",4
) );
	return TRUE;
}
La cosa strana è che legge 4 byte ma la memcmp mi ritorna 1 cioè s1
(magic) è più grande di s2 (la stringa che ci metto io in hex),
perchè ? Se io confronto 4 byte con 4 byte della mia stringa in hex
perchè memcmp mi ritorna 1 ???
Letti: 4 memcmp: 1
Colossus

 perchè memcmp mi ritorna 1 ???
Debbo mettere i caratteri, PK\03\04 per farla funzionare;se metto il
codice ascii convertito in esadecimale della P e della K: \50\4b\03\04
non funziona.
Grazie per le cortese spiegazioni.
Colossus

 perchč memcmp mi ritorna 1 ???
non ne ho idea. Probabilmente perche' i 4 byte non sono uguali.
Perche' non metti una bella
printf("%d %d %d %d\n",magic[0],magic[1],magic[2],magic[3]);
prima della tua gprint (qualunque cosa essa sia), in modo
da controllare di aver letto bene i 4 byte che ti interessano ?
A me questo programmino funziona:
#include<string.h>
#include<stdio.h>
int main(int argc, char *argv[])
{
   unsigned char magik[4];
   FILE *f;
   if (argc<2) exit(0);
   f=fopen(argv[1],"rb");
   fread(magik,1,4,f);
   fclose(f);
    printf("%d %d %d %d\n",magik[0],magik[1],magik[2],magik[3]);
   if (0==memcmp(magik,"PK\03\04",4)) printf("Zip File\n");
   else printf("Altro File\n");
   return 0;
}
e mi stampa 80 75 3 4 quando e' un file zip.
ciao,
g.


non funziona perche' (mi era sfuggito) non e' cosi' che si scrive
l'esadecimale dentro una stringa.
Dovresti scrivere qualcosa del tipo "\x50\x4b"
vai a vedere sul manuale o per esempio qui:
http://h18009.www1.hp.com/fortran/docs/lrm/lrm0035.htm
\03\04 funziona perche' le sequenze di quel tipo vengono interpretate
in ottale e in ottale 03 e 04 sono uguali a 03 e 04 in esadecimale (e 
anche in decimale).
Riassumendo: per mettere i codici esadecimali nelle stringhe li devi
far precedere da \x  quindi nel tuo caso
"\x50\x4b\x03\x04" volendo.
ciao,
g.

 ciao,
Ok, finalmente ci siamo, grazie di cuore sei stato molto 
gentile ! Avevo cercato in google come inserire un numero in 
esadecimale in C ed in effetti tutti i link che ho trovato 
dicevano di anteporre 0x e cosě ho fatto ma non funzionava,
invece nel link che mi hai dato tu dice di mettere xhh non 
0xhh, evidentemente la memcmp conta anche lo 0 vicino alla x.


 perchè memcmp mi ritorna 1 ???
Piu` grande non e` inteso in quel senso. Vuol dire che il byte che
differisce e` piu` grande di quello di riferimento.
Luca
-- 
Home: 
http://kronoz.cjb.net
Soltanto un istante...
tuffarsi nell'infinito...
annegare senza pensieri