2014-09-29 12 views
5

Se una linea non corrisponde a un formato [fsv] scanf, scanf garantisce di non toccare i puntatori forniti che non corrispondono?Fa sscanf touch pointers se non è stata trovata alcuna corrispondenza?

Per esempio, se

int int1 = 3; 
int int2 = 5; 
sscanf(line, "%d %d", &int1, &int2); 

ritorna 0, sono i numeri interi garantiti per essere ancora 3 e 5, o può int1 sono stati modificati?

+0

(Duplicato trovato da Blue Moon, sotto) –

risposta

5

La risposta breve è sì, nel vostro caso si può garantire che int1 e int2 non sono cambiati.

Tuttavia, vorrei consigliare contro affidamento su questo comportamento, in quanto è in grado di produrre codice che è difficile da leggere - e perché:


La risposta lunga è dipende dalla vostra stringa di formato. Osservando lo standard C11 per fscanf (s7.21.6.2.16), si ha:

La funzione fscanf restituisce il valore del EOF macro se si verifica un errore ingresso prima della prima conversione (se presente) ha completato . In caso contrario, la funzione restituisce il numero di elementi di input assegnati, che può essere inferiore a quello previsto o addirittura pari a zero, in l'evento di un errore di abbinamento anticipato.

criticamente importante è questa definizione di elementi di input da più avanti in 7.21.6.2:

Un elemento ingresso è definito come la più lunga sequenza di caratteri di input che non supera qualsiasi larghezza campo specificato e che è, o è un prefisso di, una sequenza di input corrispondente

così. Il numero restituito da scanf è il numero di elementi letti dallo stream, non il numero di puntatori scritti in.

Inoltre rilevante è 7.21.6.2.2:

Se il formato si esaurisce mentre rimangono argomenti, l'eccesso argomenti vengono valutati (come sempre), ma sono altrimenti ignorati.

Il comportamento di ignorare argomenti che non sono scritti È inoltre chiarito in un esempio alla fine di questa sezione:

In:

#include <stdio.h> 
    /* ... */ 
    int d1, d2, n1, n2, i; 
    i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2); 

valore 123 è assegnato a d1 e il valore 3 a n1. Poiché %n non può mai ottenere un errore di input, il valore di 3 viene anche assegnato a n2. Il valore di d2 non è interessato. Il valore 1 è assegnato a i.

Nel caso in cui non hai familiarità con %n, è "il numero di caratteri letti dal flusso finora".

Questo è un ottimo esempio per illustrare la tua domanda - qui abbiamo scritto tre puntatori e un puntatore intatto. Ma, fscanf restituisce solo 1 qui - perché ha assegnato solo un "elemento di input" dal flusso.

Quindi, nel tuo esempio, sì, se hai %d %d e lo passi qualcosa che causa 0 letture, allora sì, i puntatori non saranno toccati.

Tuttavia, se si dispone di un valore %n, la funzione potrebbe comunque restituire 0 o EOF mentre continua a utilizzare input e scrivere ai puntatori. Per esempio:

sscanf("aaa","aaa%n%d",&n1,&n2); 

Questo scrive 3 a n1, lascia n2 intatta, e restituisce EOF. E:

sscanf("aaa bbb","aaa%n%d",&n1,&n2); 

Questo scrive 3 a n1, lascia n2 intatta, e restituisce 0.

+1

Non è chiaro cosa succede in caso di errore di abbinamento. Il para quotato garantisce solo gli oggetti scansionati con successo e non dice nulla elementi non scansionati (puntatori). Mettilo in questo modo: * Se * "* scanf" funziona a zero inizializza tutti i puntatori (valori) prima della scansione effettiva, non violare nulla nello standard? –

+0

@BlueMoon mette in parole ciò che avevo in mente quando ponevo la domanda. La documentazione o le specifiche dicono qualcosa a riguardo? –

+0

Ho modificato la risposta per articolare in modo più chiaro ciò che dice lo standard. E per modificare il contenuto della mia precedente, errata risposta :) –

0

Non ci dovrebbero essere almeno come molti di questi argomenti il ​​numero dei valori memorizzati dal di formato di sscanf. Ulteriori argomenti sono ignorati dalla funzione sscanf. Se la riga contiene dire "10 20", quindi int1 e int2 saranno cambiati rispettivamente in 10 e 20. Tuttavia, se la riga contiene dire "aa bb", int1 e int2 verranno mantenuti rispettivamente come 3 e 5.

Problemi correlati