2014-09-29 16 views
5

Jeśli linia nie jest zgodna z formatem [fsv] scanf, czy gwarancja scanf nie dotyka dotkniętych wskaźników, które nie są dopasowane?Czy wskaźniki dotykowe sscanf, jeśli nie znaleziono pasującego elementu?

Na przykład, jeśli

int int1 = 3; 
int int2 = 5; 
sscanf(line, "%d %d", &int1, &int2); 

zwraca 0, są liczbami całkowitymi gwarancją jeszcze 3 i 5, albo może int1 zostały zmienione?

+0

(Duplikat znaleziony przez Blue Moon, poniżej) –

Odpowiedz

5

Odpowiedź jest krótka tak, w twoim przypadku można zagwarantować, że int1 i int2 nie zmieniły.

Jednak radziłbym przed powołując się na to zachowanie, jak to prawdopodobne, aby produkować kod, który jest trudny do odczytania - i dlatego:


Długa odpowiedź jest to zależy od formatu ciąg. Patrząc na standardzie C11 dla fscanf (s7.21.6.2.16), mamy:

Funkcja fscanf zwraca wartość makra EOF jeśli wystąpi awaria wejście przed pierwszym konwersji (jeśli w ogóle) został ukończony . W przeciwnym razie funkcja zwraca liczbę przypisanych elementów wejściowych, która może być mniejsza niż przewidziana, a nawet równa zero, w przypadku błędu wczesnego dopasowywania.

Krytycznie ważne jest to definicja elementów wejściowych z później w 7.21.6.2:

Element wejściowy jest definiowany jako najdłuższy ciąg znaków wejściowych, która nie przekracza żadnej określonej szerokości pola i który jest lub jest przedrostkiem pasującej sekwencji wejściowej.

Liczba zwrócona przez scanf to liczba elementów odczytanych ze strumienia, a nie liczba zapisanych wskaźników.

Dodatkowo istotne jest 7.21.6.2.2:

Jeśli format jest wyczerpana, podczas gdy argumenty pozostają, nadmiar argumenty są oceniane (jak zawsze), ale poza tym są ignorowane.

Zachowanie ignorowanie argumentów, które nie są zapisywane jest również wyraźnie na przykład na końcu tej sekcji:

w:

#include <stdio.h> 
    /* ... */ 
    int d1, d2, n1, n2, i; 
    i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2); 

wartość 123 jest przypisany do d1 i wartości 3 do n1. Ponieważ %n nigdy nie może uzyskać błędu wejścia, wartość 3 jest również przypisana do n2. Nie ma to wpływu na wartość d2. Wartość 1 jest przypisana do i.

Jeśli nie znasz %n, jest to "liczba znaków odczytanych ze strumienia do tej pory".

Jest to świetny przykład, aby zilustrować twoje pytanie - tutaj mamy trzy wskaźniki napisane, a jedna wskazówka nietknięta. Ale, fscanf tylko zwraca 1 tutaj - ponieważ przypisał tylko jeden "element wejściowy" ze strumienia.

Tak, w twoim przykładzie, tak, jeśli masz %d %d i przekazujesz mu coś, co powoduje 0 odczytów, to tak, wskaźniki pozostaną nietknięte.

Ale jeśli masz tam %n, twoja funkcja może nadal zwracać 0 lub EOF, nadal pobierając niektóre dane wejściowe i piszące do wskaźników. Na przykład:

sscanf("aaa","aaa%n%d",&n1,&n2); 

To pisze 3 do n1, pozostawia n2 nietknięty i zwraca EOF. Oraz:

sscanf("aaa bbb","aaa%n%d",&n1,&n2); 

To pisze 3 do n1, pozostawia n2 nietknięty i zwraca 0.

+1

Nie jest jasne, co dzieje się w przypadku niepowodzenia dopasowania. Podana para tylko gwarantuje, że przedmioty zostały zeskanowane pomyślnie i nie mówi niczego nieskanalizowanych przedmiotów (wskaźników). W ten sposób: * Jeśli funkcje * "* scanf" zera inicjują wszystkie wskaźniki (wartości) przed rzeczywistym skanowaniem, czy narusza to wszystko w standardzie? –

+0

@BlueMoon wkłada w słowa to, co było w mojej głowie, zadając pytanie. Czy dokumentacja lub specyfikacja mówią coś na ten temat? –

+0

Edytowałem odpowiedź, aby wyraźniej wyrazić, co mówi standard. I aby zmienić treść z mojej wcześniejszej, niepoprawnej, odpowiedzi :) –

0

Nie powinno być co najmniej tak wiele z tych argumentów, jak liczba wartości przechowywanych przez specyfikacją formatu sscanf. Dodatkowe argumenty są ignorowane przez funkcję sscanf. Jeśli wiersz zawiera "10 20", wtedy int1 i int2 zostaną zmienione odpowiednio na 10 i 20. Jeśli jednak wiersz zawiera "aa bb", to int1 i int2 będą zachowane odpowiednio jako 3 i 5.

Powiązane problemy