2016-02-11 17 views
14

È consentito utilizzare scanf(" ") senza argomenti aggiuntivi per ignorare gli spazi bianchi iniziali?
Sto usando getchar() per leggere i caratteri di una parola e voglio ignorare gli spazi bianchi prima della parola (spazi bianchi dopo sono usati per controllare la fine della parola).
Il codice è il seguente, è corretto?scanf senza argomenti aggiuntivi in ​​C

char *read_word() { 
    int size = 2; 
    int char_count = 0; 
    char *s; 
    char ch; 

    s = mem_alloc(size); 

    scanf(" "); 

    while ((ch = getchar()) != EOF) { 
     if (char_count >= size) { 
      s = mem_realloc(s, size++); 
     } 

     if (ch == ' ' || ch == '\n') { 
      s[char_count] = '\0'; 
      break; 
     } 

     s[char_count++] = ch; 
    } 

    return s; 
} 
+6

Assolutamente ..... – DevSolar

+2

parte: 'mem_realloc (s, dimensioni ++);' -> 'mem_realloc (s, ++ size); ' –

+0

Nota: il codice può restituire' s' che manca un carattere nullo. – chux

risposta

13

Dalla definizione della funzione scanf() (*), l'enfasi è mia:

Il formato è composto da zero o più direttive: uno o più spazi vuoti, un carattere multibyte normale (né % né un carattere di spazio bianco), o una specifica di conversione.

[...]

Una direttiva composto carattere spazio vuoto (s) viene eseguito leggendo ingresso fino al primo carattere non-bianco-spazio (che rimane non letto), oppure fino a quando non è possibile leggere più caratteri.

Quindi scanf(" "); è perfettamente valido.


(*): ISO/IEC 9899: 1999, 7.19.6.2 La fscanf funzione, sezione 3 e 5.

Le altre *scanf funzioni sono definiti in termini di questa sezione.

4

Vorrei invece provare:

int skip = -1; 
if (scanf(" %n", &skip)>=0 && skip>0) { 
    // you have skipped skip spaces 
} 

I> = 0 test controlla che scanf non ha mancato (per esempio a causa di EOF su stdin, o un errore di input). Il test skip>0 verifica che abbiamo saltato almeno un byte spacelike. Lo specificatore di conversione %n indica il numero di byte analizzati.

+0

Il test '> = 0' sembra non necessario. Come aiuta? – chux

+0

Stavo pensando che 'skip' non può essere cambiato se c'è stato EOF su stdin, o errore di input, quindi' skip' manterrebbe il suo valore -1 e quindi fallirà il test 'skip> 0'. IAC, controllando il valore restituito da 'scanf()' è qualcosa da incoraggiare. – chux

+0

Bene, se nessuno spazio è stato saltato, il mio test non funziona –

5

Il manpage dice:

stringa

Il formato è costituito da una sequenza di direttive

...

Una direttiva è una delle seguenti:

• Una sequenza di caratteri spazi bianchi (spazio, tab, newline, ecc., Vedere isspace (3)). Questa direttiva corrisponde a qualsiasi quantità di spazio bianco, incluso nessuno, nell'input.

...

così , si tratta di un uso legale di scanf.


Se siete alla ricerca di efficienza:

int c; 
while(isspace(c=getchar()) {;} 

conduce lungo un percorso più efficiente, come getchar et. al. tendono ad avere controparti _unlocked, a differenza di scanf.

+0

Anche se non si tratta di un problema in questo caso, farei attenzione a fare affidamento sulle pagine di manuale. Di solito non distinguono chiaramente tra ciò che è ISO C, e ciò che è POSIX - e che * può * fare la differenza. Quindi se la domanda riguarda se qualcosa è legale o meno "in C", la manpage di trumps standard. (E non sto dicendo questo solo perché l'ho citato, ma perché sto lavorando su e con piattaforme non POSIX di volta in volta.) – DevSolar

+0

@DevSolar Sono d'accordo. Abbiamo pubblicato praticamente contemporaneamente. Potrei non aver postato il mio se avessi visto il tuo per primo, ma penso che il mio abbia ancora un certo valore (= sto ottenendo dei punti da esso: D) quindi lo terrò. – PSkocik

+0

Si noti che per rendere l'esempio di esempio 'getchar' a' scanf ("") 'si dovrà' ungetc (c, stdin) 'alla fine. –

9

da aggiungere alle altre risposte, tutti i seguenti sono valide:

scanf(" ");  // skip over whitespace 
scanf("xyz"); // skip over the longest leading substring of "xyz" if present 
       // i.e. "xyz" or "xy" or "x" 
scanf(" %*s "); // skip over the first string and whitespace around it 
+1

apprezzare per aggiungere ulteriori conoscenze con la risposta originale - utile –