2012-06-08 10 views
6

Jak rozumiem, operator ekstrakcji pomija początkowo białe znaki i zatrzymuje się po napotkaniu białych znaków lub końca strumienia. noskipws można użyć, aby przestać ignorować wiodące spacje.Wpływ noskipws na cin >>

Mam następujący program, w którym użyłem noskipws.

#include <iostream> 
using namespace std; 

int main() 
{ 
    char name[128]; 

    cout<<"Enter a name "; 
    cin>>noskipws>>name; 
    cout<<"You entered "<<name<<"\n"; 

    cout<<"Enter another name "; 
    cin>>name; 
    cout<<"You entered "<<(int)name[0]<<"\n"; 

    return 0; 
} 

Moje pytania są następujące:

  1. Jeśli wejdę „John” jako pierwszego wejścia, potem drugi cin >> operacja nie czekać na wejście i nie kopiować niczego do IE docelowego tablica nazw. Spodziewałem się, że drugi ciąg >> przeniesie co najmniej znak nowej linii lub końca strumienia, zamiast tylko ustawić ciąg docelowy, aby był pusty. Dlaczego to się dzieje ?

  2. To samo jest przestrzegane, gdy wpisuję "John Smith" jako dane wejściowe dla pierwszego wyrażenia cin >>. Dlaczego drugie zdanie cin >> nie kopiuje spacji lub "Smitha" do zmiennej docelowej?

Poniżej znajduje się wyjście z programu:

Enter a name John 
You entered John 
Enter another name You entered 0 


Enter a name John Smith 
You entered John 
Enter another name You entered 0 

Dzięki !!!

+0

Mam nadzieję, że wiesz, że program może produkować przepełnienia bufora bardzo łatwo. W kodzie produkcyjnym nie powinieneś używać 'std :: cin' do zapisu w tablicy char. Zamiast tego użyj 'std :: string'. – smerlin

+0

To prawda. Powyższy kod służy wyłącznie do celów ilustracyjnych. Używanie cin.width lub cin.getline pozwala uniknąć niektórych problemów z przepełnieniem, ale jak już wspomniano, std :: string byłoby najlepsze. Podałem powyższy przykładowy kod tylko po to, aby pokazać, o co chciałem zapytać. –

Odpowiedz

10

Podstawowy algorytm >> z ciągiem jest:

skip whitespace 
read and extract until next whitespace 

Jeśli używasz noskipws, to pierwszy krok jest pomijany. Po pierwszym przeczytaniu jesteś pozycjonowany na białych znakach, więc następne (i wszystkie następne) odczyty zatrzymają się natychmiast, nie wyodrębniając niczego.

>> na ciąg nigdy nie wstawi białych znaków do łańcucha. Bardziej ogólnie, używanie >> z noskipws jest problematyczne, ponieważ biała spacja jest zawsze separatorem dla >>; może być sensowne, aby używać go punktualnie, ale generalnie należy go zresetować natychmiast po użyciu. (Niegdyś przypadek, gdy może to mieć sens jest przy użyciu >> do char. W tym przypadku, strumień zawsze ekstrakty jeden znak.)

+0

Dobra, rozumiesz. Ale jestem zdezorientowany co do tego, dlaczego wkład "John Smith" nie spowodował, że operator >> skopiował "Smitha" w drugiej operacji wprowadzania. Dlaczego "Smith" zniknął całkowicie ze strumienia wejściowego i nawet wtedy druga operacja cin nie czekała na dane wejściowe. –

+2

@AchintMehta Ponieważ następny znak do odczytania to biała spacja, a nie "S" w "Smith". Powiedziałeś, żeby nie pomijać białych znaków, więc tak nie jest. Następnie wprowadza do, ale bez uwzględnienia następnego odstępu, który jest natychmiastowy. '' Smith "' nie znika, po prostu go nie czytasz. I nie można go odczytać z '>>', z wyjątkiem '>>' do 'char', ponieważ wszystkie inne' >> 'zatrzymają się na pierwszych białych znakach, wyodrębniając nic i nie przesuwając pozycji wejściowej. –