2016-05-08 27 views
9

Ich möchte eine Zeile sscanf und stellen Sie sicher, dass es nichts mehr gibt, als was ich darin wollte. Der Code sieht wie folgt aus:Wie scansf um sicherzustellen, dass der Puffer genau das ist, was ich wollte?

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); 
    } 
} 

Wenn ich eine Eingabe wie bekommen:

INIT 9 11 3 1 1 1 9 

alles ist in Ordnung, aber dann eine Eingabe wie dieses ist

INIT 9 11 3 1 1 1 9 s 

auch angenommen. Ich dachte, wenn ich "\ n" hinzufüge, würde alles gut funktionieren, da ich weiß, dass jede Eingabezeile mit einem EOL endet, aber das tat es nicht.

+3

'scanf' behandelt das Zeichen für neue Zeilen als Leerzeichen, genau wie Tabulatoren und Leerzeichen. Sie könnten einen neunten Dummy-Wert lesen, eine kurze Zeichenfolge mit erzwungenem max. width ('% 2s') vielleicht und erzwinge, dass die Anzahl der Conversions nicht über 8 liegt. –

+0

Wird der Puffer initialisiert, bevor er in diese Funktion übergeben wird? – bentank

Antwort

2

So etwas könnte es tun, wenn Ihre Eingabe immer einen Zeilenumbruch am Ende hat. Der Code erfordert einen zusätzlichen char Typ und überprüft, dass es \n, sowie die richtige Anzahl der gescannten Elemente ist. Es druckt 1 für den Erfolg - eine leichte Abweichung zu Ihrer Funktion für den Zweck dieses Beispiels.

#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; 
} 

Programm Sitzungen von der Tastatur:

INIT 9 11 3 1 1 1 9 
1 

INIT 9 11 3 1 1 1 9 s 
0 

Hinweis kein führendes Leerzeichen vor %c ist, die Leerzeichen übersprungen werden verursachen würde, den Sieg über den Punkt es zu haben.

+2

Das wird einen schwer erklärbaren Fehler verursachen, wenn der Benutzer "INIT 9 11 3 1 1 1 9" (mit einem Leerzeichen am Ende) eingibt. Ich mag @ MOehms Lösung besser (in einem Kommentar zum OP). – rici