Nei miei esperimenti questa espressioneQual è il risultato di `strtod (" 3ex ", & end)` dovrebbe essere? Che dire di `sscanf`?
double d = strtod("3ex", &end);
inizializza d
con 3.0
e pone end
puntatore 'e'
carattere nella stringa di input. Questo è esattamente come mi aspetto che si comporti. Il carattere 'e'
potrebbe sembrare un inizio della parte esponente, ma poiché manca il valore di esponente effettivo (richiesto dalla 6.4.4.2), tale 'e'
deve essere considerato come un carattere completamente indipendente.
Tuttavia, quando lo faccio
double d;
char c;
sscanf("3ex", "%lf%c", &d, &c);
mi accorgo che sscanf
consuma sia '3'
e 'e'
per il formato %lf
specificatore. La variabile d
riceve il valore 3.0
. La variabile c
termina con 'x'
. Questo mi sembra strano per due ragioni.
In primo luogo, dato che la specifica del linguaggio riferisce a strtod
nel descrivere il comportamento di %f
di formato, intuitivamente aspettato %lf
per trattare l'ingresso nello stesso modo strtod
fa (cioè scegliere la stessa posizione del punto terminale). Tuttavia, so che storicamente lo scanf
doveva restituire non più di un carattere al flusso di input. Ciò limita la distanza di qualsiasi look ahead scanf
può essere eseguito da un solo carattere. E l'esempio sopra richiede almeno due caratteri di previsione. Quindi, supponiamo che accetti il fatto che lo %lf
abbia consumato sia '3'
sia 'e'
dal flusso di input.
Ma poi ci imbattiamo nel secondo numero. Ora sscanf
deve convertire quello "3e"
nel tipo double
. "3e"
non è una rappresentazione valida di una costante in virgola mobile (anche in questo caso, secondo 6.4.4.2 il valore dell'esponente non è facoltativo). Mi aspetto che sscanf
consideri errato questo input: termina durante la conversione %lf
, restituisce 0
e lascia d
e c
invariato. Tuttavia, il precedente sscanf
viene completato correttamente (restituendo 2
).
Questo comportamento è coerente tra le implementazioni GCC e MSVC della libreria standard.
Così, la mia domanda è: dove esattamente nel linguaggio C standard di documento non si permette sscanf
a comportarsi come sopra descritto, facendo riferimento a questi due punti: che consumano più di strtod
fa e con successo la conversione di tali sequenze come "3e"
?
Osservando i risultati del mio esperimento probabilmente posso "decodificare" il comportamento dello sscanf
: consumare quanto "sembra giusto" senza mai tornare indietro e quindi passare semplicemente la sequenza consumata a strtod
. In questo modo, 'e'
viene consumato da %lf
e quindi viene semplicemente ignorato da strtod
. Ma lo erano esattamente le specifiche del linguaggio?
Forse la ragione (sebbene non una scusa molto buona) della differenza sta nel fatto che 'sscanf' è in' stdio' e 'strtod' è in' stdlib'. –
Non sono sicuro di aver capito: perché il risultato di sscanf ti sembra strano? Cosa ti aspettavi esattamente? Potresti fornire qualche dettaglio in più? – HighPredator
@HighPredator: OP probabilmente significa che la variabile 'c' dovrebbe raggiungere il valore' 'e'' e non il valore '' x''. O forse non dovrebbe raggiungere alcun valore, e la funzione 'sscanf' dovrebbe restituire 1 invece di 2 (quindi emula esattamente il comportamento di' strtod'). –