Grazie![]()
Grazie![]()
Tra l'altro, se devi concatenare tante stringhe la sprintf è anche più efficiente: se fai:
ciascuna strcat deve scorrersi la stringa fino in fondo per sapere da dove iniziare a copiare; al contrario, una sprintfcodice:char buf[1024]="asd"; strcat(buf, var1); strcat(buf, var2); strcat(buf, var3); strcat(buf, var4); strcat(buf, var5);
tiene traccia internamente di dove è arrivata, per cui in ultima analisi risulta più efficiente.codice:char buf[1024]; sprintf("asd%s%s%s%s%s", var1, var2, var3, var4, var5);
Amaro C++, il gusto pieno dell'undefined behavior.
Era esattamente questo che volevo capire inizialmente! Grazie mille![]()
@Dany_ occhio che sprintf di per sé può portare a buffer overflow. Il codice sopraesposto non controlla che le var* entrino in buf. Usa snprintf per maggiore sicurezza:
e controlla che abbia successo. man sprintf(3)codice:snprintf(buff, sizeof(buf), format, ...);
Ultima modifica di signoredeltempo; 18-01-2015 a 18:59
Io ho fatto così:
Va bene lo stesso? Nel senso che avendo calcolato prima la dimensione di buf in base a quello che ci devo mettere dentro, quando faccio la sprintf dovrebbe essere tutto ok immagino!codice:char *buf; buf = calloc(lunghezzaDesiderata + 1, sizeof(char)); sprintf(buf, ".....", ...);
Quella è parte della soluzione. O usi snprintf o controlli la lunghezza di ogni membro (cosa ripetitiva per tipi non-stringa).
Es:
codice:char buf[5]; sprintf(buff, "%d", 123456789); // buffer overflow
Cioè sarebbe più corretto così?
codice:char *buf; buf = calloc(lunghezzaDesiderata + 1, sizeof(char)); snprintf(buf, sizeof(buf), ".....", ...);
Sì. Citando man sprintf
Because sprintf() and vsprintf() assume an arbitrarily long string, callers must be careful not to overflow the actual space; this is often
impossible to assure. Note that the length of the strings produced is
locale-dependent and difficult to predict. Use snprintf() and
vsnprintf() instead (or asprintf(3) and vasprintf(3)).
Facendo così però ho un warning che dice:
"argument to ‘sizeof’ in ‘snprintf’ call is the same expression as the destination; did you mean to provide an explicit length?"
Grazie, gentilissimo![]()