C: byte di padding

di il
28 risposte

C: byte di padding

Buonasera,
i valori

float a;
double b; 
char c1, c2, c3;
short int d;
char c4;
long int e;
disposti in tale ordine occupano in memoria uno spazio pari a 24 byte, poiché c'è un byte di padding dopo c3 e uno dopo c4.. giusto?

Però, facendo un programma che legga e stampi a schermo questi valori scritti in un file binario, il mio ragionamento non torna.. In particolare b=0.000000 per ogni valore inserito, inoltre ho notato che, utilizzando fseek per spostare il puntatore, vengono stampati sbagliati anche d, c4, e, cosa che non accade, ad eccezione di e, non utilizzandolo.

#include <stdio.h>
#include <stdlib.h>

int main() {

FILE *fp;
fp = fopen("es17.dat", "r");

float a;
double b; 
char c1, c2, c3;
short int d;
char c4;
long int e;

fread(&a, sizeof(float), 1, fp);
printf("a: %f\n", a);

fread(&b, sizeof(double), 1, fp);
printf("b: %f\n", b);

fread(&c1, sizeof(char), 1, fp);
printf("c1: %c\n", c1);

fread(&c2, sizeof(char), 1, fp);
printf("c2: %c\n", c2);

fread(&c3, sizeof(char), 1, fp);
printf("c3: %c\n", c3);

fseek(fp, 2, 1);            //sposto il puntatore di 2 byte dalla posizione corrente(va alla casella 17)

fread(&d, sizeof(short int), 1, fp);
printf("d: %hd\n", d);

fread(&c4, sizeof(char), 1, fp);
printf("c4: %c\n", c4);

fseek(fp, 2, 1);           //casella 21

fread(&e, sizeof(long int), 1, fp);
printf("e: %ld\n", e);

fclose(fp);
return 0;
}

28 Risposte

  • Re: C: byte di padding

    Stai leggendo da un file esistente? Scritto come?
  • Re: C: byte di padding

    Eh, un file binario
  • Re: C: byte di padding

    Ma quindi il problema qual è? Non si capisce ...

    Cosa avevi scritto nel file ?
  • Re: C: byte di padding

    Il tuo ragionamento non tornerebbe nemmeno se le variabili indicate fossero in una struttura. Nel tuo caso sono allocate localmente.

    Come gia richiesto da oregon devi farci vedere il codice con cui hai/è stato creato il file da cui vuoi leggere i dati.
  • Re: C: byte di padding

    Ho inserito i valori nel file binario con questo programma:
    
    #include <stdio.h>
    #include <stdlib.h>
    
    struct struttura {
     float a;
      double b;
      char c1, c2, c3;
      short int d;
      char c4;
      long int e;
     };
     
     int main() {
      FILE *fp;
      fp = fopen("es17.dat", "w");
      struct struttura s;
      
      printf("inserisci float: ");
      scanf("%f", &s.a);
      getchar();
      fwrite(&s.a, sizeof(float), 1, fp);
      
       printf("inserisci double: ");
      scanf("%f", &s.b);
      getchar();
      fwrite(&s.b, sizeof(double), 1, fp);
      
        printf("inserisci char: ");
      scanf("%c", &s.c1);
      getchar();
      fwrite(&s.c1, sizeof(char), 1, fp);
      
        printf("inserisci char: ");
      scanf("%f", &s.c2);
      getchar();
      fwrite(&s.c2, sizeof(char), 1, fp);
      
        printf("inserisci char: ");
      scanf("%f", &s.c3);
      getchar();
      fwrite(&s.c3, sizeof(char), 1, fp);
      
        printf("inserisci short int: ");
      scanf("%hd", &s.d);
      getchar();
      fwrite(&s.d, sizeof(short int), 1, fp);
      
        printf("inserisci float: ");
      scanf("%c", &s.c4);
      getchar();
      fwrite(&s.c4, sizeof(char), 1, fp);
    
      printf("inserisci long int: ");
      scanf("%ld", &s.e);
      getchar();
      fwrite(&s.e, sizeof(long int), 1, fp);
    
    fclose(fp);
    return 0;
    }
    
    
    Però l'esercizio mi impone di rileggere, con il programma che vi ho scritto ieri, i valore dal file binario senza usare la scruct.
    Comunque, perché il mio ragionamento sarebbe sbagliato?
  • Re: C: byte di padding

    Ti consiglio di controllare BENE quando scrivi perché ci sono un po' di errori nelle scanf ... hai fatto confusione con i copia-incolla.
    Se metti a posto tutto va bene e non ci sono i problemi di cui parli (e che in effetti erano molto confusi ... il padding non c'entra nulla ...).

    Se inserisci i valori da 1 a 8 i byte presenti nel file sono

    00 00 80 3F 00 00 00 00 00 00 00 40 33 34 35 06 00 37 08 00 00 00

    e sono corretti.
  • Re: C: byte di padding

    Ma nel comando dell'esercizio c'è scritto "fare attenzione ai byte di padding"
  • Re: C: byte di padding

    Ma tu il testo dell'esercizio non l'hai mai postato e non hai mai spiegato correttamente il problema.

    Così come l'hai posto il problema non c'è.

    Forse dovevi scrivere TUTTA la struttura e non solo i singoli elementi come hai fatto?
  • Re: C: byte di padding

    "Scrivere un programma in C in cui sia definita una struct contenente questi campi: un float, un double,
    tre char, uno short int, un char, un long int, in questo ordine. Creare una di queste struct, assegnare
    valori di riferimento a piacere a ogni campo e salvare la struct su un file binario.
    Scrivere poi un altro programma in C che legga e stampi a schermo i valori dal file binario senza pero'
    usare la struct ma leggendo ogni elemento dal file singolarmente; per esempio, per leggere lo short int
    si dovra' usare una variabile short int nella chiamata a fscanf. Si presti attenzione ai byte di padding."
  • Re: C: byte di padding

    "salvare la struct su un file binario."

    Quindi devi fare una sola fwrite della struttura, non per ogni elemento !
  • Re: C: byte di padding

    Fai inoltre attenzione al byte padding, in quanto c'è un double nella struttura quindi non è come pensi tu. Dipende inoltre dall'architettura per cui stai compilando:

    Su una macchina a 64 bit il seguente codice:
    
    #include <stdio.h>
    
    struct struttura
    {
    	float a;
    	double b;
    	char c1, c2, c3;
    	short int d;
    	char c4;
    	long int e;
    };
    
    int main()
    {
    	struct struttura test;
    
    	printf("sizeof(struct struttura): %zu\n", sizeof(struct struttura));
    
    	printf("a : %p\n", (void *)(&test.a ));
    	printf("b : %p\n", (void *)(&test.b ));
    	printf("c1: %p\n", (void *)(&test.c1));
    	printf("c2: %p\n", (void *)(&test.c2));
    	printf("c3: %p\n", (void *)(&test.c3));
    	printf("d : %p\n", (void *)(&test.d ));
    	printf("c4: %p\n", (void *)(&test.c4));
    	printf("e : %p\n", (void *)(&test.e ));
    	return 0;
    }
    
    da come risultato
    
    sizeof(struct struttura): 32
    a : 0x7ffde9dc6bf0
    b : 0x7ffde9dc6bf8
    c1: 0x7ffde9dc6c00
    c2: 0x7ffde9dc6c01
    c3: 0x7ffde9dc6c02
    d : 0x7ffde9dc6c04
    c4: 0x7ffde9dc6c06
    e : 0x7ffde9dc6c08
    
  • Re: C: byte di padding

    Come verrebbe fwrite con la struttura intera?
  • Re: C: byte di padding

    Prova a scriverla ... non mi pare difficile ...
  • Re: C: byte di padding

    Fwrite (&(struct struttura), sizeof(struct struttura), 1, fp)?
Devi accedere o registrarti per scrivere nel forum
28 risposte