2012-10-16 11 views
9

wejściowego składa się łańcuch i liczbę całkowitą, które są oddzielone '/' coś takiego:użyciu scanf czytać ciąg i int oddzielony/

hello/17 

I chcę czytać wejście do ciąg i int, tak:

char str[20]; 
int num; 
scanf("%s/%d", str, &num); // this how I tried to do it. 

i nie wydaje się, aby to, jakieś rady?

+0

Interesujące pytanie. 'scanf' może mieć coś do symulacji pasujące więcej niż z'% s'. – Eregrith

Odpowiedz

13

scanf czeka na przerwany ciąg znaków w białej spacji, gdy próbuje odczytać %s.

Spróbuj określić ustawić zabronione znak bezpośrednio:

scanf("%[^/]/%d", str, &num); 

można przeczytać więcej na temat kodów formatowania here

+1

Ostrożnie, wpisałeś '% d' zamiast'% s' na pierwszej pozycji – Eregrith

7

Wystarczy tylko uruchomić następujący program:

#include <stdio.h> 

int main (void) { 
    char str[20] = {'\0'}; 
    int count, num = 42; 

    count = sscanf ("hello/17", "%s/%d", str, &num); 

    printf ("String was '%s'\n", str); 
    printf ("Number was %d\n", num); 
    printf ("Count was %d\n", count); 

    return 0; 
} 

do zobacz, dlaczego tak się dzieje. Dane wyjściowe to:

String was 'hello/17' 
Number was 42 
Count was 1 

Przyczyna jest związana ze specyfikatorem formatu %s. Od C99 7.19.6.2 The fscanf function (w dużej mierze niezmienione w C11, a kursywą moje):

s: dopasowuje sekwencję non-white-space znaków.

Od / nie jest biała przestrzeń, zostaje włączone w łańcuch bitów, tak jak 17 z tego samego powodu. Wskazuje na to również fakt, że sscanf zwraca 1, co oznacza, że ​​zeskanowano tylko jeden obiekt: jeden.

To, czego będziesz szukać, to coś, co skanuje dowolne znaki inne niż / w ciągu znaków (w tym białe znaki). Ta sama sekcja standardu pomaga również:

[: dopasowuje niepustą sekwencję znaków ze zbioru oczekiwanych znaków (zestawu skanów). Specyfikator konwersji obejmuje wszystkie kolejne znaki w ciągu formatów, aż do prawego nawiasu pasującego()) włącznie. Znaki między nawiasami (lista skanów) tworzą zestaw skanów, chyba że znak po lewym nawiasie jest okalający (^), w takim przypadku zestaw skanów zawiera wszystkie znaki, które nie pojawiają się na liście skanowania między oknem a prawym wspornikiem.

Innymi słowy, coś jak:

#include <stdio.h> 
int main (void) { 
    char str[20] = {'\0'}; 
    int count, num = 42; 

    count = sscanf ("hello/17", "%[^/]/%d", str, &num); 

    printf ("String was '%s'\n", str); 
    printf ("Number was %d\n", num); 
    printf ("Count was %d\n", count); 

    return 0; 
} 

co daje:

String was 'hello' 
Number was 17 
Count was 2 

jeden inny radę: Nigdy kiedykolwiek korzystanie scanf z bezgranicznym %s , pytasz o atak polegający na przepełnieniu bufora. Jeśli potrzebujesz solidnej funkcji wprowadzania danych, zobacz this answer.

Po wprowadzeniu go jako ciąg, możesz sscanf go do treści serca bez obawy o przepełnienie bufora (ponieważ masz ograniczony rozmiar na wejściu).

+0

dzięki za szczegółową odpowiedź. – Alcott