2013-04-01 9 views
12
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 

char *method1(void) 
{ 
    static char a[4]; 
    scanf ("%s\n", a); 
    return a; 
} 

int main(void) 
{ 
    char *h = method1(); 
    printf ("%s\n", h); 
    return 0; 
} 

Kiedy uruchomić powyższy kod, monit prosi mnie dwukrotnie dla wejścia (ja używam tylko scanf raz w kodzie). Dlaczego?scanf pytając dwukrotnie do wejścia, a ja spodziewałem się, że prosić tylko raz

+0

Jakie wyjście otrzymałeś? –

+0

To bardzo krótka tablica. Czy wprowadziłeś zbyt dużo danych? –

+0

Wchodzę w jo. prosi o kolejne wejście. , a następnie wchodzę ponownie jo. to tylko wydrukować jo jeden raz. – joy

Odpowiedz

17

Z mojego scanf stronie podręcznika

Białe znaki (takie jak wykroje, kart lub znaków nowej linii) w ciągu formatu dopasować dowolną ilość białej przestrzeni, w tym żaden, na wejściu. Wszystko inne pasuje tylko do siebie.

Tak więc z scanf ("%s\n", a) będzie skanować ciąg znaków, a następnie opcjonalnie białe spacje. Ponieważ po pierwszym znaku nowej linii może pojawić się więcej białych znaków, funkcja scanf nie zostanie wykonana po pierwszym znaku nowej linii i będzie wyglądała następująco. Zauważysz, że możesz wprowadzić dowolną liczbę nowych linii (lub tabulatorów lub spacji), a scanf nadal będzie czekał na więcej.

Jednak po wprowadzeniu drugiego ciągu sekwencje białych znaków są rozdzielane, a skanowanie zatrzymuje się.

Użyj polecenia scanf ("%s", a), aby nie skanować końcowych spacji.

7

musisz usunąć \n z formatu ciągów znaków scanf. Powinno być

scanf("%s",a); 

EDIT: Objaśnienie

%s oznacza, że ​​scanf czyta znak wejściowy aż robi się ogranicznik, który powinien pojawić się biała przestrzeń jak przestrzeń lub karcie lub w nowym wierszu (\n) więc pierwsze wejście otrzymujemy jako separator dla "%s", a dodanie "\n" do formatu łańcuchów "%s\n" oznacza, że ​​scanf będzie czekał 2 nowe linie Pierwszy znak nowej linii jest powiązany z separatorem "%s", a drugi znak nowej linii jest powiązany z \n ul format pierścienia.

+2

Jesteś na dobrej drodze, ale nie powiedziałeś, że 'scanf' będzie nadal czytał białą przestrzeń, dopóki nie natrafi na postać nie-kosmiczną. Możesz wprowadzić wiele nowych linii (i pustych lub tabulatorów) zanim nie wprowadzisz spacji i zatrzymasz 'scanf'. Jeszcze jeden powód, by preferować 'fgets()' i 'sscanf()' w wariancie pliku I/O 'scanf()'. –

+1

Twoje rozumowanie, że scanf czeka na dwa nowe linie, jest błędne. Wszystkie nowe znaki (nawet więcej niż dwa) są skanowane przez ** pojedynczy ** '\ n' w formacie, podobnie jak wszystkie przeplatające się spacje i tabulatory.Proszę przeczytać specyfikację scanf w standardzie C lub na stronie podręcznika. – Jens

-1

użyć gets() lub fgets() zamiast ... alternatywnie użyj scanf ("% [^ \ n] s", a);

+0

scanf wprowadza do tablicy, aż otrzyma spację ... użyj% [^ \ n] s ... lub nie używaj scanf, zamiast tego przejdź do fgets() lub dostaje() –

+2

'"% [^ \ n] s "' składa się z dwóch dyrektyw: '% [^ \ n]', które albo dopasowują (i przechowuje) jeden lub więcej znaków innych niż "\ n" lub kończą się niepowodzeniem, ponieważ natychmiast natrafiają na '\ n' i ' s', który pasuje do literału 's' i odrzuca go, lub zawiedzie i przesuwa z powrotem znak 'non' na standardowe wejście. Pierwsza dyrektywa nie powiedzie się dla kolejnych prób, ponieważ '\ n' nie jest 's', więc '\ n' zostanie zepchnięty z powrotem na standardowe wejście i jest to pierwszy napotkany znak. Zobacz sam: 'char a [64]; int n = scanf ("% [^ \ n] s", a); assert (n == 1); n = scanf ("% [^ \ n] s", a); assert (n == 1); ' – Sebivor

+0

Moja sugestia to przeczytanie instrukcji [fscanf] (http://pubs.opengroup.org/onlinepubs/007904975/functions/fscanf.html), abyś mógł wyjaśnić zamieszanie w odniesieniu do dyrektywy '% [' i '% s'. – Sebivor

0

Nie używaj sekwencji ucieczki w funkcji scanf stdio

 scanf ("%s", a); 
+2

Nie ma wyjaśnienia, dlaczego - i co się stanie, gdy to zrobisz. To nic nie dodaje do [odpowiedzi] (http://stackoverflow.com/a/15740060/) autorstwa [MOHAMED] (http://stackoverflow.com/users/1003575/mohamed) lub zaakceptowanej odpowiedzi. –

-1

Usuń/n od scanf i dać sygnał wejściowy i wyświetla dane wyjściowe na podstawie danego wyjścia raz.

+0

Niepoprawny ukośnik. Ta odpowiedź nie dodaje nic do poprzednich odpowiedzi. –