Newsgroup: it.comp.lang.c
Titolo: Utilizzo "stringizing operator"

Ciao a tutti,
cominciamo con l'esempio del manuale :
#define debug(x) printf ( #x  " = %ld", x );
debug ( Ciao );
sostisce con
printf ( "Ciao = %d", Ciao );
Io avrei bisogno di fare una cosa simile se possibile:
sprintf ( Buffer, "Ciao" );
debug ( Buffer );   ----->>>>> printf ( "Ciao = %d", Ciao );
sprintf ( Buffer, "Miao" );
debug ( Buffer );   ----->>>>> printf ( "Miao = %d", Miao );
sprintf ( Buffer, "Bau" );
debug ( Buffer );   ----->>>>> printf ( "Bau = %d", Bau );
senza dover controllare il contenuto di Buffer e quindi
scrivere tonnellate di codice ( poter fare la
stessa cosa che in CLIPPER si fa con la macro "&"
se qualcuno conosce ).
Grazie per l'aiuto
:-) Olga



 wrote in message
| Io avrei bisogno di fare una cosa simile se possibile:
|
| sprintf ( Buffer, "Bau" );
| debug ( Buffer );   ----->>>>> printf ( "Bau = %d", Bau );
| senza dover controllare il contenuto di Buffer e quindi
| scrivere tonnellate di codice ( poter fare la
| stessa cosa che in CLIPPER si fa con la macro "&"
| se qualcuno conosce ).
Una cosa del genere?
#ifdef _DEBUG_SPRINTF
    #define DSPRINTF((BUF), (X)) sprintf((BUF), #(X));\
     printf ( #(X)" = %ld", (X))
#else
    #define DSPRINTF((BUF), (X)) ; /* null code o quello che vuoi */
#endif
--
PGP public key available

 wrote in message 384ab...@news.megasys.it...
| Una cosa del genere?
|
| #ifdef _DEBUG_SPRINTF
|     #define DSPRINTF((BUF), (X)) sprintf((BUF), #(X));\
|      printf ( #(X)" = %ld", (X))
| #else
|     #define DSPRINTF((BUF), (X)) ; /* null code o quello che vuoi */
| #endif
forse e' meglio:
#ifdef _DEBUG_SPRINTF
    #define DSPRINTF(BUF, X) {sprintf((BUF), #X);\
printf (#X" = %ld\n", (X));}
#else
    #define DSPRINTF(BUF, X)
#endif
cosi' compila, pure :)
W

 #endif
Scusa ma forse mi sono spiegata male :
io ho un file di configurazione che mi dice
che la variabile CodiceArticolo deve essere stampata
alla posizione X,Y la variabile Descrizione deve
essere stampata alla posizione X,Z e cosi' via.
Dopo la lettura del file avrei in Buffer il nome della
variabile "CodiceArticolo" e dovrei utilizzare la
variabile CodiceArticolo in stampa.
Volevo sapere se era possibile utilizzare attraverso
Buffer le variabili che mi leggo dal file senza dover
fare un controllo sul contenuto di Buffer e poi con
tanti (troppi) if eseguire le stampe delle varie cose.
Grazie per l'aiuto.
:-) Olga :-)

 wrote in message 8k44h4$1g7
| Volevo sapere se era possibile utilizzare attraverso
| Buffer le variabili che mi leggo dal file senza dover
| fare un controllo sul contenuto di Buffer e poi con
| tanti (troppi) if eseguire le stampe delle varie cose.
puoi fare un esmpio in pseudo-codice?
tipo:
...
funzioni varie in cui
<carico tutti i nomi in buffer>
...
funzione stampa:
<finche' buffer non e' vuoto>:
  leggi variabile;
  stampa debug;
(che e' come ho capito le cose...)

 tanti (troppi) if eseguire le stampe delle varie cose.
Non in modo portabile e supportato dallo Standard C.
I nomi che a tempo di compilazione hai dato alle tue
variabili "si perdono" (a norma di standard) a tempo
di esecuzione.  Nulla impedisce a un particolare
compilatore di tenerli in giro, ad esempio a scopo
di debugging, ma non puoi far conto sul fatto che
esistano, men che meno su come accedervi.
Devi dunque costruirti tu una tabella di corrispondenza
fra il nome che vuoi esternamente esporre per una data
variabile, e (ad esempio) l'indirizzo di memoria a cui
si dovra` fare riferimento.  Nulla ti vincola comunque
ad esporre esternamente nomi identici a quelli che usi
internamente, anche se nulla te lo proibisce.
Supponiamo ad esempio che tutte le variabili di
interesse siano int globali (o piu` precisamente,
di lifetime static).  Potresti allora avere nel tuo
programma anche questa tabella globale:
typedef struct name_addr_t {
    const char* name;
    int* addr;
} name_addr_t;
name_addr_t name_addr_table[] = {
    {"CodiceArticolo", &CodiceArticolo},
    {"Pippo", &Pippo},
    {"Pluto", &Pluto},
    {0,0}
};
dove ho usato {0,0} come terminatore.  La ricerca
dell'indirizzo da usare per un dato nome sara`
naturalmente delegata ad una funzioncina apposta:
int* name_to_addr(const char* name)
{
    name_addr_t* pna = &name_addr_table[0];
    while(pna->name) {
        if(0==strcmp(pna->name,name))
            return pna->addr;
        ++pna;
    }
    return 0;
}
Questa funzione torna 0 se non trova il nome.
Lascio a te i raffinamenti, come l'uso di un
confronto indipendente da minuscole/maiuscole,
ad esempio.  Nota, comunque, che di "if" ne
abbiamo dovuto scrivere uno solo!-)
Puo` essere comodo incapsulare la costruzione
della tabella in un paio di utili macro, cosi`
che appaia in una forma simile ad esempio a:
NAME_TABLE_BEGIN()
    NAME_TABLE_ENTRY(CodiceArticolo)
    NAME_TABLE_ENTRY(Pippo)
    NAME_TABLE_ENTRY(Pluto)
NAME_TABLE_END()
Non e` naturalmente difficile scrivere le macro
(hint: considera lo "stringizing" fatto da #
su di un argomento di una macro:-).
Alex

Grazie a tutti per l'aiuto.
Ciao Olga :-)