C: byte di padding

di Anonimizzato21674 il
28 risposte
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

  • Stai leggendo da un file esistente? Scritto come?
  • Eh, un file binario
  • Ma quindi il problema qual è? Non si capisce ...

    Cosa avevi scritto nel file ?
  • 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.
  • 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?
  • 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.
  • Ma nel comando dell'esercizio c'è scritto "fare attenzione ai 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?
  • "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."
  • "salvare la struct su un file binario."

    Quindi devi fare una sola fwrite della struttura, non per ogni elemento !
  • 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
    
  • Come verrebbe fwrite con la struttura intera?
  • Prova a scriverla ... non mi pare difficile ...
  • Fwrite (&(struct struttura), sizeof(struct struttura), 1, fp)?
Devi accedere o registrarti per scrivere nel forum
28 risposte