Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

rozdzial/lekcja 26, zadanie nr 2

Ostatnio zmodyfikowano 2022-04-14 21:48
Autor Wiadomość
jebackoze
Temat założony przez niniejszego użytkownika
rozdzial/lekcja 26, zadanie nr 2
» 2022-04-11 22:49:04
hej,
prosze o rzucenie okiem, czy kod jest wlasciwy.

punkt 1
C/C++
#include <iostream>
#include <limits>
#include <string>
#include <cstdlib>

void wczytajOsobe( std::string & imie, std::string & nazwisko, int & wiek )
{
   
   
std::cout << "podaj imie i nazwisko: ";
   
std::cin >> imie >> nazwisko;
   
do
   
{
       
std::cin.clear();
       
std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );
       
std::cout << "podaj wiek: ";
       
std::cin >> wiek;
   
} while( std::cin.fail() );
   
}

wypiszOsobe( std::string imie, std::string nazwisko, int wiek )
{
   
std::cout << "\n" << imie << " " << nazwisko << ", " << wiek << ". " << std::endl;
}

int main()
{
   
std::string imie[ 2 ];
   
std::string nazwisko[ 2 ];
   
int wiek[ 2 ];
   
for( int i = 0; i < 2; i++ )
       
 wczytajOsobe( imie[ i ], nazwisko[ i ], wiek[ i ] );
   
   
for( int i = 0; i < 2; i++ )
       
 wypiszOsobe( imie[ i ], nazwisko[ i ], wiek[ i ] );
   
   
return 0;
}



punkt 2. czegos nie moge zauwazyc bo nie dziala to wlasciwie, musze dodatkowy enter wcisnac zeby przejsc do podawania wieku. wklejam fragment kodu bo reszta jest jak w powyzszym. zagladam zarowno do lekcji jak i do FAQ. domyslam sie, ze petla do w ktorej czyszcze bufor powoduje problem z nowa linia po nazwisku. gdzie popelniam blad? ale jak usune z petli czyszczenie to z petli przeciez nie wyjde jak podam bledne dane.
C/C++
( ... )
void wczytajOsobe( std::string & imie, std::string & nazwisko, int & wiek )
{
   
std::cout << "podaj imie: ";
   
std::getline( std::cin, imie );
   
std::cout << "podaj nazwisko: ";
   
//std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' ); // obojetnie czy tu
   
std::getline( std::cin, nazwisko );
   
//std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' ); // czy tu, wymaga 1 entera wiecej
   
   
do
   
{
       
std::cin.clear();
       
std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );
       
std::cout << "podaj wiek: ";
       
std::cin >> wiek;
   
} while( std::cin.fail() );
   
   
std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );
}
( ... )

EDYCJA: jesli zamiast std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' ); uzyje std::cin.sync(); to problemu nie ma i dziala to prawidlowo.


EDYCJA 2: zrobilem taka wersje kodu i zaskoczylo, pytanie czy to prawidlowo albo czy da sie to jeszcze skrocic?
C/C++
void wczytajOsobe( std::string & imie, std::string & nazwisko, int & wiek )
{
   
std::cout << "podaj imie: ";
   
std::getline( std::cin, imie );
   
std::cout << "podaj nazwisko: ";
   
std::getline( std::cin, nazwisko );
   
   
bool test;
   
do {
       
std::cout << "podaj wiek: ";
       
std::cin >> wiek;
       
test = std::cin.fail();
       
std::cin.clear();
       
std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );
   
} while( test );
   
}
P-179393
pekfos
» 2022-04-12 17:10:41
ignore powinno być użyte w odpowiedzi na błąd, a nie przed wczytywaniem. Chcesz zignorować tu linię tekstu, wiec musisz podać tę linię tekstu. Działa po wczytywaniu przez >> bez żadnego warunku, bo operator >> zostawia w strumieniu wszystko od pierwszego błędnego znaku, w co wlicza się znak nowej linii. Póki naciskasz enter po każdej wartości, zawsze masz linię tekstu którą można zignorować bez czekania na dodatkowe dane od użytkownika. std::cin.sync() jest błędnym rozwiązaniem.
P-179394
jebackoze
Temat założony przez niniejszego użytkownika
» 2022-04-12 22:35:11
@pekfos, przyznam szczerze, ze chyba nie rozumiem tego co napisales albo mam gorszy dzien bo nie moge zatrybic.

C/C++
void wczytajOsobe( std::string & imie, std::string & nazwisko, int & wiek )
{
   
std::cout << "podaj imie: ";
   
std::getline( std::cin, imie );
   
std::cout << "podaj nazwisko: ";
   
std::getline( std::cin, nazwisko );
   
   
do {
       
std::cout << "podaj wiek: ";
       
std::cin >> wiek;
       
std::cin.fail();
       
std::cin.clear();
       
std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );
   
} while( std::cin.fail() );

wez mi prosze tu latarka poswiec bo nie moge tego odpalic zgodnie z zalozeniem.

z kolei to mi dziala:
C/C++
( ... )
bool test;
do {
   
std::cout << "podaj wiek: ";
   
std::cin >> wiek;
   
test = std::cin.fail();
   
std::cin.clear();
   
std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );
} while( test );
P-179395
pekfos
» 2022-04-12 22:44:23
fail() odczytuje bieżącą informację o błędzie, a clear() ją czyści. W tym wypadku interesujący jest błąd operacji wczytywania operatorem >>, więc musisz sprawdzić błąd przed clear() i zapisać wynik do użycia później.
P-179396
jebackoze
Temat założony przez niniejszego użytkownika
» 2022-04-12 23:09:40
czyli wynik  std::cin.fail();  musze zapisac do jakiejs zmiennej, ktora bedzie wykorzystana przy while do sprawdzenia wyjscia.
czyli ten kod z bool powinien byc ok? zamiast bool, moge dac po prostu int test; i tez bedzie ok?

jesli zly trop to chyba musze elementarz dla podstawowki 1-3 kupic...
P-179397
pekfos
» 2022-04-13 17:12:42
Tak. Może być też int, tylko po co?
P-179398
jebackoze
Temat założony przez niniejszego użytkownika
» 2022-04-13 18:53:16
bo nie mam pomyslu czy i gdzie lezy blad.
moj kod wyglada tak i wg mnie dziala, ale jesli cos jest z nim nie tak to po prostu nie moge tego dojrzec (;
C/C++
( ... )
bool test; //lub int
do {
   
std::cout << "podaj wiek: ";
   
std::cin >> wiek;
   
test = std::cin.fail();
   
std::cin.clear();
   
std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );
} while( test );

( ... )

P-179399
pekfos
» 2022-04-13 21:21:59
Ale jaki jest błąd? Ten kod sam w sobie jest ok.
P-179400
« 1 » 2
  Strona 1 z 2 Następna strona