2011-10-30 15 views
5

Dlaczego ten konkretny fragment kodu zwraca false na strstr(), jeśli wprowadzam "test"?strstr nie działa

char input[100]; 

int main() 
{ 
    fgets(input, 100, stdin); 
    printf("%s", input); 

    if(strstr("test message", input)) 
    { 
     printf("strstr true"); 

    } 


} 

Myślałem, że strstr przeszukał pierwszy parametr pod kątem wystąpienia drugiego paramu? Działa, gdy zastępuję dane wejściowe jakimś tekstem lub po prostu przypisuję je bezpośrednio, ale wydaje się, że nie działa z fgetami.

+0

Jeśli chodzi o problem, istnieje http://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input –

Odpowiedz

10

Dzieje się tak dlatego, że fgets przechowuje znak nowego wiersza, więc gdy strstr dokonuje porównania, kończy się niepowodzeniem.

Od strony man:

fgets() odczytuje co najwyżej jeden mniej niż size znaków ze strumienia i zapisuje je do bufora wskazywanego przez s. Czytanie zatrzymuje się po EOF lub nowej linii. Jeśli zostanie odczytany znak nowej linii, zostanie on zapisany w buforze . "\ 0" jest przechowywane po ostatnim znaku w buforze.

+0

Usuń prawdopodobnie i otrzymasz +1 :) – FailedDev

+0

@sashang ta część dokumentu jest nadal myląca. Mówi EOF lub nowa linia. Który to jest? Przeglądałem samouczek, który mnie zawiódł. Zastąpienie ostatniego znaku pustym '\ 0' spowodowało, że samouczek spowodował, że' fgets' automatycznie wstawił '\ 0', gdy w rzeczywistości wstawił' \ n'. Z tego powodu 'strstr' nie działał. Ale dlaczego książka mówi, że to zadziała? – Andy

+0

@Andy: "EOF lub nowa linia" oznacza EOF lub znak nowej linii lub obie z nich. "lub" tutaj ma znaczenie logicznego boolowskiego lub nie "lub" używanego w potocznym angielskim. Dlatego oba są poprawną odpowiedzią. – sashang

6

Dodaj input[strlen(input) - 1] = '\0'; po fgets. fgets czyta w znaku nowej linii ('\n'). Nie ma w nim nigdy nie być zawartego elementu '\n'.

Naprawdę powinieneś sprawdzić, czy nowa linia znajduje się na końcu bufora po wywołaniu fgets, aby wiedzieć, czy cała linia była w stanie faktycznie do niej pasować, a także, oczywiście, usunąć ją.

+0

Czy mogę założyć, że gdy 'fgets' czyta, powiedz,' "Hello" ', to faktycznie czyta' "Hello \ n \ 0" 'lub' "Hello \ n" '. – Andy

+0

Odczytuje "" Witaj \ n "', a następnie przerywa ciąg znaków za pomocą '\ 0''. Ale to tylko wtedy, gdy czyta się znak nowej linii. – AusCBloke

+0

Pozwolę sobie zmienić zdanie. Jaki powinien być wynik "fget"? Pytam, ponieważ 'strstr' nie działa. Kiedy robię 'variable [strlen (variable) -1] = '\ 0'', to działa. Kiedy 'strlen' analizuje łańcuch na długość, czy pomija on kończącą wartość pustą? Więc '" Hello \ n \ 0 "', czy to 6, ponieważ zawiera znak nowej linii? A jeśli tak, to wynikiem byłoby "" Hello \ 0 \ 0 "' jeśli tak, jak rozwiązałbym mój problem, który jest trochę marnotrawny. Dziękuję za poświęcony czas. – Andy