Se voglio un programma per avere più formati di output di testo, avrei potuto fare qualcosa di simile:Esiste un codice printf "null" che non stampa nulla, usato per saltare un parametro?
const char *fmtDefault = "%u x %s ($%.2f each)\n";
const char *fmtMultiLine = "Qty: %3u\nItem: %s\nPrice per item: $%.2f\n\n";
const char *fmtCSV = "%u,%s,%.2f\n";
const char *fmt;
switch (which_format) {
case 1: fmt = fmtMultiLine; break;
case 2: fmt = fmtCSV; break;
default: fmt = fmtDefault;
}
printf(fmt, quantity, item_description, price);
Poiché il prezzo è specificato scorso, potrei anche aggiungere uno che non elencare i prezzi:
const char *fmtNoPrices = "%u x %s\n";
Ma cosa succede se invece voglio omettere la quantità? Se ho fatto questo:
const char *fmtNoQuantity = "The price of %s is $%.2f each.\n";
quindi si verificherà un comportamento non definito (molto probabilmente un segfault) piuttosto che quello che voglio. Questo perché tratterà il primo parametro come puntatore a una stringa, anche se in realtà è un int unsigned. Molto probabilmente questo int unsigned punta a qualcosa di diverso da dati stringa validi o (molto più probabilmente, soprattutto se non stai comprando centinaia di milioni dello stesso articolo), una posizione di memoria non valida, causando un errore di segmentazione.
Quello che voglio sapere è se c'è un codice posso mettere da qualche parte (%Z
in questo esempio) per dirgli di saltare quel parametro, in questo modo:
const char *fmtNoQuantity = "%ZThe price of %s is $%.2f each.";
scanf() può utilizzare gli asterischi, ma IIRC printf() non può. Ho anche provato a usare '.0' specificatori di precisione, ma questo sembra funzionare solo su stringhe ('% .0s' non visualizzerà nulla, ma probabilmente ancora dereferenzia il puntatore se non è null) – Medinoc
Dovresti usare insiemi separati di chiamate con elenchi di argomenti separati, penso. Fare altrimenti rende l'internazionalizzazione (I18N) molto più difficile. –