Newsgroup: it.comp.lang.c
Titolo: Printf di un campo all'interno di struct

Ciao a tutti,
non riesco a capire perche' la seconda printf del campo num_ord della
struct tr_a mi stampi tutto il record anziche' solo il campo di 10
byte. Anche le ultime due printf, dove gli si dice di stampare
rispettivamente 5 byte e 10 byte non capisco perche' si comporta in
quel modo.
Qualcuno puo' aiutarmi?
Grazie in anticipo.
Marco
printf("lth_num  => %d \n", lth_num_ord=sizeof(pline_a->num_ord));
printf("num      => %s\n" ,      pline_a->num_ord);
printf("num 10.10=> %10.10s \n", pline_a->num_ord);
printf("num 10.05=> %10.5s \n",  pline_a->num_ord);
printf("num 10.05=> %-10.5s \n", pline_a->num_ord);
printf("num 05.10=> %5.10s \n",  pline_a->num_ord);
printf("num     5=> %5s \n",     pline_a->num_ord);
printf("num    10=> %10s \n",    pline_a->num_ord);
Risultato delle printf:
lth_num  => 10
num      => 0000000001TITOLOABC120070215100001000
num 10.10=> 0000000001
num 10.05=>      00000
num 10.05=> 00000
num 05.10=> 0000000001
num     5=> 0000000001TITOLOABC120070215100001000
num    10=> 0000000001TITOLOABC120070215100001000
fileA.txt
0000000001TITOLOABC120070215100001000
0000000002TITOLOBBC120070215151201000
0000000003TITOLOCBC120070215150001000
0000000004TITOLODBC120070216150001000
0000000011TITOLOFBC120070216150001000
0000000012TITOLOSBC120070216150001000
0000000067TITOLOVBC120070216150001000
Programma:
/*****************************************
 *   Lettura di un file riga per riga.   *
 *****************************************/
#define LINUX
#ifdef LINUX
#define NOME_FILE_A "/home/marco/development/dati/fileA.txt"
#define NOME_FILE_B "/home/marco/development/dati/fileB.txt"
#define NOME_FILE_C "/home/marco/development/dati/fileC.txt"
#else
#define NOME_FILE_A "C:\\temp\\fileA.txt"
#define NOME_FILE_B "C:\\temp\\fileB.txt"
#define NOME_FILE_C "C:\\temp\\fileC.txt"
#endif
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<ctype.h>
struct tr_a {
	char num_ord[10];
	char titolo[10];
	char data[8];
	char ora[6];
	char filler[3];
} *pline_a;
struct {
	char num_ord[10];
	char tipo[02];
	char qta[9];
	char filler[3];
} *pline_b;
struct {
	char num_ord[10];
	char qta_tot[02];
	char data[8];
	char ora[6];
} file_c;
FILE *fp_a;
FILE *fp_b;
FILE *fp_c;
#define LIMITE_MAX 128   /* limite massimo in cui mettere la
stringa_letta letta:
			  se la stringa_letta letta fosse più lunga, viene troncata */
char buffer_a[LIMITE_MAX+1];
char buffer_b[LIMITE_MAX+1];
FILE * apri_files(char *, char[]);    /* prototipo di funzione*/
char *leggi_file(FILE *, char *);      /* prototipo di funzione*/
void msg_errore(char *, int);         /* prototipo di funzione*/
int main(int argc, char *argv[])
{
int lth_num_ord=0;
	fp_a = apri_files(NOME_FILE_A,"r");
	fp_b = apri_files(NOME_FILE_B,"r");
	fp_c = apri_files(NOME_FILE_C,"w");
	if ((leggi_file(fp_a, buffer_a)) == NULL) {
	    msg_errore(NOME_FILE_A, 3);
        }
	if ((leggi_file(fp_b, buffer_b)) == NULL) {
	    msg_errore(NOME_FILE_B, 3);
        }
	do {
		if(isalnum(buffer_a[0]))
		{
			pline_a = (struct tr_a *)buffer_a;
			printf("lth_num  => %d \n", lth_num_ord=sizeof(pline_a->num_ord));
			printf("num      => %s\n" ,      pline_a->num_ord);
			printf("num 10.10=> %10.10s \n", pline_a->num_ord);
			printf("num 10.05=> %10.5s \n",  pline_a->num_ord);
			printf("num 10.05=> %-10.5s \n", pline_a->num_ord);
			printf("num 05.10=> %5.10s \n",  pline_a->num_ord);
			printf("num     5=> %5s \n",     pline_a->num_ord);
			printf("num    10=> %10s \n",    pline_a->num_ord);
		}
       } while( leggi_file(fp_a, buffer_a) != NULL);
  fclose(fp_a);
  return (0);
}
/****************************
* lettura file              *
****************************/
char *leggi_file(FILE *fd, char Pstringa[])
{
  return( fgets(Pstringa, LIMITE_MAX, fd));
}
/*****************
* Apertura files *
******************/
FILE *apri_files(char *file_da_aprire, char modalita_apertura[])
{
  FILE *fd;
  printf("\nFile da aprire=> %s\n", file_da_aprire);
  fd=fopen(file_da_aprire, modalita_apertura);
  if( fd==NULL ) {
	 msg_errore(NULL, 2);
	 }
	 return(fd);
}
/************************************
* stampa messaggio d'errore a video*
************************************/
void msg_errore(char *msg, int num_errore)
{
  switch (num_errore){
  case 1:
		 printf("\n Il programma \"%s\" %s\n\n", msg, "richiede in input il
nome del file da stampare");
		 exit(1);
		 break;
  case 2:
		 /*perror - print a system error message */
		 printf("Errore in apertura file %s \n", msg);
		 exit(1);
		 break;
  case 3:
		 /*perror - print a system error message */
		 perror("Errore in lettura file");
		 exit(1);
		 break;
  default:
		 /*perror - print a system error message */
		 perror("Errore non codificato");
		 break;
  }
}

 byte.
Evidentemente l'array non è terminato con un NUL ('\0'). E anche gli array
successivi, pare. 
Non c'è niente di sbagliato nell'usare array di char che non sono terminati
da NUL, basta tenere presente non puoi stamparli con printf né usarli con
funzioni come strcpy, strlen e parenti.
Max


buffer_a[] contiene una stringa;quando lo leggi come una struttura,
non esite nessun terminatore all'interno, quindi il %s prende tutto
quello che trova


Ok, ho capito.
Allora cosa consigliate: se devo leggere un file di testo, e il record
che leggo lo metto in una struct per poter dividere i campi e
trattarli singolarmente, devo prima trasformarli in stringhe ogni
volta e poi trattarli?
L'obiettivo è di leggere due file di testo ed eseguire dei test sui
singoli campi che potrebbero essere stringhe di testo oppure campi
numerici.
Grazie
Marco

 numerici.
E' questa riga che non va tanto bene.
    pline_a = (struct tr_a *)buffer_a;
Fai una conversione un po' "brutale".
Tra l'altro non ci sono neanche controlli che verificano che il formato
della riga letta sia conforme ai vari campi attesi.
Dovresti espandere questa riga con una serie di istruzioni che, dopo la
lettura di una riga, vanno a leggere il buffer dove č stata salvata la riga
letta verificando la presenza e la correttezza dei singoli campi e poi li
salvano nei vari campi della struct.
Se alcuni campi sono numeri, data, ora, ... potrebbe aver senso convertirli
e salvarli nella struct in un formato diverso che non sia una stringa di
caratteri (dipende che cosa ci devi fare dopo). Nel caso salvi tutto in
formato stringa puņ essere di aiuto terminare le stringhe con un carattere
null, soprattutto se la stringa non č di lunghezza costante.