2012-11-21 12 views
25

mam parsowania ciąg (a char*) i używam sscanf do analizowania liczb z ciągu znaków w deblu, w taki sposób:Uzyskaj liczbę znaków przeczytanych przez sscanf?

// char* expression; 
double value = 0; 
sscanf(expression, "%lf", &value); 

Działa to doskonale, ale ja wtedy chciał kontynuować podczas analizowania sznur przez konwencjonalne środki. Muszę wiedzieć, ile znaków zostało przeanalizowanych przez sscanf, aby móc wznowić moje ręczne analizowanie z nowego offsetu.

Oczywiście, najprostszym sposobem byłoby jakoś obliczyć liczbę znaków, które sscanf analizuje, ale jeśli nie ma prosty sposób, aby to zrobić, ja am otwarty do alternatywnych opcji podwójnych analizowania. Jednak obecnie używam sscanf, ponieważ jest szybki, prosty i czytelny. Tak czy inaczej, po prostu potrzebuję sposobu, aby ocenić podwójne i kontynuować przetwarzanie po nim.

Odpowiedz

39

Można użyć formatu specyfikatora %n i stanowić dodatkowy argument sscanf()int *:

int pos; 
sscanf(expression, "%lf%n", &value, &pos); 

Opis formatu specyfikatora n ze standardu C99:

No input jest spożywana. Odpowiednim argumentem będzie wskaźnik do liczby całkowitej ze znakiem, do której ma zostać zapisana liczba znaków odczytanych ze strumienia wejściowego do tej pory przez to wywołanie funkcji. Wykonanie dyrektywy %n nie zwiększa liczby przydziałów zwróconych po zakończeniu wykonywania funkcji fscanf. Żaden argument nie jest konwertowany, ale jeden jest zużywany. Jeśli specyfikacja konwersji zawiera znak ograniczający przydział lub szerokość pola, zachowanie jest niezdefiniowane.

Zawsze należy sprawdzić wartość zwracaną sscanf() aby upewnić się, że zadania zostały wykonane, a następnie kod nie omyłkowo zmienne procesowe, których wartości były niezmienione:

/* Number of assignments made is returned, 
    which in this case must be 1. */ 
if (1 == sscanf(expression, "%lf%n", &value, &pos)) 
{ 
    /* Use 'value' and 'pos'. */ 
} 
+0

Nie mogę sprawić, aby działał on w ramach [implementacji Microsoft] (https://msdn.microsoft.com/en-us/library/t6z7bya3.aspx?f=255&MSPPError=-2147217396) jako takiej: ' sscanf_s (p, "% s% d \ n% n", toString, (int) _countof (toString) i itemCount, &pos); '' pos' nie wydaje się zmieniać w ogóle. – c00000fd

2
int i, j, k; 
char s[20]; 

if (sscanf(somevar, "%d %19s %d%n", &i, s, &j, &k) != 3) 
    ...something went wrong... 

Zmienna k zawiera liczbę znaków aż do miejsca, w którym został zeskanowany koniec liczby całkowitej zapisanej w j.

Pamiętaj, że %n nie jest liczony w udanych konwersjach. Możesz użyć %n kilka razy w ciągu znaków, jeśli potrzebujesz.

Powiązane problemy