Czyszczenie strumienia wejsciowego

0

Ogolnie to powiem wam ze nie zabardzo rozumiem dzialanie tego:


std::cin.clear();
std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );

mam opis:
"Powyższy zapis ignoruje do 1000 znaków znajdujących się w strumieniu wejściowym. Jeżeli w strumieniu wejściowym zostanie napotkany znak nowego wiersza '\n' proces ignorowania znaków zostanie zakończony. Proces ignorowania znaków nie zostanie jednak zakończony gdy w buforze nie będzie więcej znaków do odczytania. Jeżeli chcesz używać tej techniki to należy czyścić strumień wejściowy po każdym wczytaniu danych by uniknąć ewentualnych problemów technicznych związanych ze sposobem działania tej metody."
No i opis tego ze to pierwsze czysci flagi bledu a drugie bufor tzn ignoruje znaki w nim.

Ale mimo wszystko nie zabardzo rozumiem, czyli jak to jest podaje pierwsza liczbe normalnie, w drugiej powiedzmy podaje znak *, i on teraz znajduje sie w buforze wejsciowym ale jest ignorowany przez druga linijke tak ? On znika w ktoryms momencie ? i to cale , 'n/' na koncu linijki, jest opisane ze beda znaki ignorowane pÓÓÓÓki to sie tam nie pojawi, i faktycznie wpisuje to w dzialajacym programie i crashuje go z powodu wczesniej wpisanych znakow, ale gdy tego nie podam to program dziala w nieskonczonosc... a wiec jak dokladnie dziala i co robi to '\n' na koncu tego wiersza ? Ogolnie prosilbym o lopatologicznie wytlumaczenie tych dwoch linijek bo nie moge troche tego ogarnac.

4

Chyba niewiele rozumiesz. Podajesz jakieś dane do bufora. Jeśli próbujesz czytać z bufora strumieniami bo sprawdzany jest typ czytanych danych. Jeśli próbujesz czytać inta a ktoś podał na wejście coś innego niż liczbę, to strumień ustawi się w stanie błędu i odmówi czytania. Od teraz każda próba czytania tym strumieniem zakończy sie błędem.
cin.clear powoduje usunięcie flagi błędu i strumień znów jest użyteczny. Ale w buforze wejściowym nadal jest ta nie-liczba i próba odczytania inta znów spowoduje błąd. Jeśli jesteś pewien że czytasz liczby to możesz postanowić skasować nie-liczbowy input użytkownika.
cin.ignore powoduje usunięcie z bufora N znaków, ewentualnie aż do napotkania jakiegoś konkretnego symbolu.
\n to znak nowej linii. Jak wpisujesz liczby i zatwierdzasz je "enterem" to dodawana jest automatycznie nowa linia (bo przecież enter powoduje że coś ci przeskakuje "linijkę niżej").

0

Temat jest prosty..
Grzyby i porosty :D
Nie, ale tak serio, to temat wcale nie jest taki prosty, i na twoim poziomie wtajemniczenia nie musisz dokładnie wiedzieć co robi cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );, bo po prostu nie jest Ci to raczej potrzebne, jest to prawdopodobnie(niech ktoś to potwierdzi) niezawodny(przenośny) sposób wczytywania danych, bo poleca go sam twórca języka w tym linku źródło.
Natomiast literał \n jest wpisywany do bufora gdy wciśniesz enter.

0

Okej wszystko rozumiem oprocz tego '\n'
No bo powiedzmy ze podaje znak zamiast liczby, zeby program dalej mogl dzialac, te linie usuwaja flage bledu i "usuwaja" znak z bufora, dochodze do nastepnego cin >> - i tutaj wpisuje juz normalnie liczbe i zatwierdzam ja enterem, czy to nie powinno znowu "powrocic" znaku do bufora ?

2

Nie, bo domyślnie ustawiony jest tryb pomijania białych znaków jak czytasz . Przykład: w kodzie masz

int x,y,z;
cin>>x>>y>>z;

W konsoli wpisujesz 1 2 3 czyli pomiędzy liczbami są spacje / białe znaki a mimo to strumień te inty wczytuje a białe znaki pomija. Patrz np. na taki kod:

#include <iostream>
using namespace std;

int main() {
	char c = 'x';
	cin>>noskipws>>c;
	cout<<int(c);
	return 0;
}

Jeśli po prostu stukniesz enter na klawiaturze to program wypisze 10 bo \n ma numer 10 w ASCII. Gdyby w kodzie nie było noskipws to stuknięcie entera nic by nie dało i program nadal czekałby na dane.
Więc jak widzsz strumień czasem wyciąga białe znaki i pomija a czasem nie.
Podanie \n jako delimitera zakłada że użytkownik mógł źle wpisać jedną linijkę danych a kolejne juz poprawnie. Zamiast tego mógłbyś tam mieć EOF i wtedy ignore skasowałby wszystko co jest na wejściu. Byłoby to o tyle niewygodne ze często pętli się program do czasu kiedy na wejściu nie będzie EOFa (czyli dopóki program ma jeszcze dane do czytania). Taki ignore automatycznie skończyłby program.

0

nie rozumiem :(

2

to zostaw to w spokoju idz do czegoś prostszego. Zrozumienie przyjdzie z czasem.

0

Kurcze ale chce zrozumiec bo potem znowu dojde do dalszej czesci kursu i stane w miejscu ;c
@Edit
Moze zrozumialem, opisze jak ja to rozumiem a jesli zle to poprawcie... A wiec:
w momencie jak wpisuje znak i zatwierdzam to enterem to cin.ignore usuwa to co wpisalem przed tym jak nacisnalem enter a po tym jak zatwierdzilem ten znak ktory wpisalem enterem, konczy ignorowanie kolejnych znakow i pozwala mi wpisac przy nastepnym cin >> cos innego, tak ?

0

pozwole sobie na maly refresh i pytanie:

  • w ktorym momencie ta linia ignore spotyka ten \n ? i co sie wtedy dzieje ze znakami w buforze
1

Zostaw to na razie w spokoju.
Naprawdę, jeśli jeszcze tego nie rozumiesz, to nie ma nic w tym dziwnego.
A na pewno z tego powodu nie nie poradzisz sobie z kursem. //ale zabawne to podwójne zaprzeczenie wyszło ;p

0

tak, zgrywus z ciebie ;d

0

ej cin.ignore na pewno usuwa tez prawidlowo podane liczby ? skoro usuwa tez prawidlowo podane liczby to czemu potem dobrze mi je zwraca ?
Autor kursu napisal ze tylko w podaniu blednych znakow bedzie mozna zobaczyc dzialanie tego cin.ignore a wiec jak to mozliwe ze prawidlowe liczby tez usuwa ?

0

Gościu, odpuść sobie to cin.ignore, naprawde.
Więcej sie nauczysz przerabiając dalej kurs niż zastanawiając sie nad tym co jest Ci na razie ABSOLUTNIE niepotrzebne do szczęścia, potrafisz dobrze wczytać dane - i super, nie dociekaj bo zmarnujesz czas.

0

dobra ale powiedz jeszcze jak to ignore usuwa tez liczby skoro wczytuje je mi potem normalnie ?

0

jest istotne bo napisalem taki program

#include <iostream>
#include <limits>
using namespace std;

int wczytajLiczbe()
{
  int liczba = 0;
  do
  {
      std::cin.clear();
      std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
      cin >> liczba;
  }while (!std::cin.good());
}
int main()
{
  std::cout << "Podaj liczbe: ";
  int liczba1 = wczytajLiczbe();
  std::cout << "Podales liczbe: " << liczba1 << std::endl;
  return 0;
}

i liczba1 ciagle zwraca mi 0 bez roznicy co wpisze i nie wiem czemu ;c
i co zrobic zeby cin pytal o liczbe dopuki podajemy zle znaki ?

0

Pokaż mi gdzie zwracasz z tej funkcji jakąś wartość. I dare you.

0

Dobra skonczylem xd oficjalny kod wyglada tak:

 1#include <iostream>
 2#include <limits>
 3using namespace std;
 4
 5int wczytajLiczbe()
 6{
 7  int liczba = 0;
 8  do
 9  {
10    std::cin.clear();
11    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
12    cout << "Podaj prawidlowa liczbe: ";
13    cin >> liczba;
14  }while(!(cin.good()));
15  return liczba;
16}
17int main()
18{
19  cout << "Podaj liczbe: ";
20  int liczba1 = wczytajLiczbe();
21  std::cout << "Podales liczbe: " << liczba1 << std::endl;
22  return 0;
23}

troche dluzylem temtat ale naprawde chcialem go zrozumiec, mysle ze moge juz kroczyc dalej, dzieki wam :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1