2016-05-08 27 views
9

Mi piacerebbe sscanf una linea e assicurarsi che non ci sia nulla di più di ciò che volevo. Il codice è simile al seguente:Come sscanf per assicurarsi che il buffer sia esattamente quello che volevo?

void parse_init_command(char *buffer, command *new_command) { 
    if (sscanf(buffer, 
     "%s %d %d %d %d %d %d %d\n", 
     new_command->name, 
     &new_command->data[0], 
     &new_command->data[1], 
     &new_command->data[2], 
     &new_command->data[3], 
     &new_command->data[4], 
     &new_command->data[5], 
     &new_command->data[6]) != 8) { 
     strncpy(new_command->name, "WRONG_INPUT", 15); 
    } 
} 

Quando ottengo un ingresso come:

INIT 9 11 3 1 1 1 9 

tutto è andato bene, ma poi un ingresso come questo

INIT 9 11 3 1 1 1 9 s 

è anche accettato. Ho pensato che se avessi aggiunto "\ n" tutto funzionerebbe bene, poiché so che ogni riga di input termina con un EOL, ma non è così.

+3

'scanf' tratta il carattere di nuova riga come spazio bianco, proprio come le schede e gli spazi. Si può leggere un nono valore fittizio, una stringa breve con massimo forzato. width ('% 2s') forse, e imporre che il numero di conversioni non superi 8. –

+0

Il buffer è inizializzato prima di essere passato in questa funzione? – bentank

risposta

2

Qualcosa come questo potrebbe farlo se il tuo input ha sempre una nuova riga alla fine. Il codice richiede un altro char tipo e controlla che sia \n, nonché il numero corretto di elementi scansionati. Stampa 1 per il successo: una leggera variazione della funzione ai fini di questo esempio.

#include <stdio.h> 

typedef struct { 
    char name[100]; 
    int data[7]; 
} command; 

int parse_init_command(char *buffer, command *new_command) { 
    char eol = 0; 
    int num = sscanf(buffer, "%s%d%d%d%d%d%d%d%c", 
           new_command->name, 
           &new_command->data[0], 
           &new_command->data[1], 
           &new_command->data[2], 
           &new_command->data[3], 
           &new_command->data[4], 
           &new_command->data[5], 
           &new_command->data[6], 
           &eol); 
    return num == 9 && eol == '\n'; 
} 

int main(void) 
{ 
    char inp[50]; 
    command rec; 
    fgets(inp, sizeof inp, stdin); 
    printf("%d\n", parse_init_command(inp, &rec)); 
    return 0; 
} 

sessioni del programma da tastiera:

INIT 9 11 3 1 1 1 9 
1 

INIT 9 11 3 1 1 1 9 s 
0 

notare non c'è spazio iniziale prima %c che causerebbe spazi bianchi da saltare, sconfiggendo il punto di averlo.

+2

Questo creerà un errore difficile da spiegare quando l'utente digita 'INIT 9 11 3 1 1 1 9' (con uno spazio alla fine.) Mi piace la soluzione di @Mehm meglio (in un commento all'OP). – rici