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

[Rozdział 26]Zadanie 1

Ostatnio zmodyfikowano 2015-11-30 23:23
Autor Wiadomość
Matis28
Temat założony przez niniejszego użytkownika
[Rozdział 26]Zadanie 1
» 2015-11-29 16:09:11
Cześć mam problem z moim kodem.Oto on:
C/C++
#include <string>
#include <iostream>
#include <limits>

using namespace std;

void wczytajOsobe( string & imie, string & nazwisko, int & wiek ) {
    int i = 0;
    cout << "Podaj " <<( i + 1 ) << " imie: ";
    do {
        cin.clear();
        cin.ignore( numeric_limits < streamsize >::max(), '\n' );
        cin >> imie[ i ];
        if( cin.good != true ) {
            cout << "wprowadzono bledna wartosc" << endl;
        }
        else {
            i++;
        }
    } while( i != 2 );
   
   
    i = 0;
    cout << "Podaj " <<( i + 1 ) << " nazwisko: ";
    do {
        cin.clear();
        cin.ignore( numeric_limits < streamsize >::max(), '\n' );
        cin >> nazwisko[ i ];
        if( cin.good != true ) {
            cout << "wprowadzono bledna wartosc" << endl;
        }
        else {
            i++;
        }
    } while( i != 2 );
   
   
    i = 0;
    cout << "Podaj " <<( i + 1 ) << " wiek: ";
    do {
        cin.clear();
        cin.ignore( numeric_limits < streamsize >::max(), '\n' );
        cin >> wiek[ i ];
        if( cin.good != true ) {
            cout << "wprowadzono bledna wartosc" << endl;
        }
        else {
            i++;
        }
    } while( i != 2 );
   
}

void wypiszOsobe( string imie, string nazwisko, int wiek ) {
    cout << "Imie: " << imie << endl << "Nazwisko: " << nazwisko << endl << "Wiek: " << wiek << endl;
}

int main()
{
    string imie[ 2 ];
    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 ] );
   
    system( "pause" );
    return 0;
}
Sprawa wygląda tak. Wydaje mi się że wszystko jest poprawnie jednak gdy chcę skompilować kod wyrzuca mi błędy przy warunkach if'a oraz nie rozumiem dlaczego podkreśla mi i w tej linijce
cin >> wiek[ i ];
P-141091
Bornegio
» 2015-11-29 16:20:41
Jaki komunikat błędu? Co się kompilatorowi nie podoba?
P-141093
Matis28
Temat założony przez niniejszego użytkownika
» 2015-11-29 16:31:07
Wywaliło mi takie błędy:

1error C3867: 'std::ios_base::good': non-standard syntax; use '&' to create a pointer to member
1warning C4805: '!=': unsafe mix of type 'bool (__thiscall std::ios_base::* )(void) const' and type 'bool' in operation
1error C2446: '!=': no conversion from 'int' to 'bool (__thiscall std::ios_base::* )(void) const'
1: note: There are no conversions from integral values to pointer-to-member values
1error C2040: '!=': 'bool (__thiscall std::ios_base::* )(void) const' differs in levels of indirection from 'int'
P-141094
Bornegio
» 2015-11-29 16:42:20
Dobra już wiem.

Zmienna wiek w metodzie wczytajosobe() jest typu int. Int nie jest tablicą, więc nie możesz przy przypisywaniu podać indeksu. W przypadku Nazwiska i imienia nie ma problemu (przy kompilacji, bo program nie będzie działał prawidłowo), bo zmienne typu string są tablicami znaków char. Dlatego przy przypisywaniu im wartości przypisze tylko znak i znak od początku. Rada? Wywal tablice z z metody wszytajosobe i zapisz je w normalnej zmiennej. Ponadto i tak pobieranie jest podwójnie zapętlnone. Pobieranie dwa razy jest zadeklarowane już w funkcji main, więc program pobiera dane 4 razy zamiast 2.
P-141097
Bornegio
» 2015-11-29 16:46:01
Opcje rozwiązania ogólnie są 2.

Albo jako argumenty funkcji przyjmujesz tablice, wtedy w funkcji main nie może być pętli for. Albo Pozostawiasz tak jak jest, że funkcja przyjmuje jako argument zmienną a nie tablice i w tej funkcji nie występują żadne pętle (z wyjątkiem do while sprawdzającej poprawność wprowadzonych danych)
P-141098
Bornegio
» 2015-11-29 16:54:28
Tutaj masz wględnie poprawiony kod.

#include <string>
#include <iostream>
#include <limits>

using namespace std;

void wczytajOsobe( string & imie, string & nazwisko, int & wiek ) {
    cout << "Podaj "<< " imie: ";
    do {
        cin.clear();
        cin.ignore( numeric_limits < streamsize >::max(), '\n' );
        cin >> imie;
        if( cin.good() != true ) {
            cout << "wprowadzono bledna wartosc" << endl;
        }
    } while(!cin.good());


    cout << "Podaj " << " nazwisko: ";
    do {
        cin.clear();
        cin.ignore( numeric_limits < streamsize >::max(), '\n' );
        cin >> nazwisko;
        if( cin.good() != true ) {
            cout << "wprowadzono bledna wartosc" << endl;
        }
    } while( !cin.good());

    cout << "Podaj "<< " wiek: ";
    do {
        cin.clear();
        cin.ignore( numeric_limits < streamsize >::max(), '\n' );
        cin >> wiek;
        if( cin.good() != true )
            cout << "wprowadzono bledna wartosc" << endl;
    } while(!cin.good());

}

void wypiszOsobe( string imie, string nazwisko, int wiek ) {
    cout << "Imie: " << imie << endl << "Nazwisko: " << nazwisko << endl << "Wiek: " << wiek << endl;
}

int main()
{
    string imie[ 2 ];
    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;
}
P-141100
Matis28
Temat założony przez niniejszego użytkownika
» 2015-11-29 17:12:23
doprowadziłem kod do takiego stanu
C/C++
#include <string>
#include <iostream>
#include <limits>

using namespace std;

void wczytajOsobe( string & imie, string & nazwisko, int & wiek ) {
    cout << "Podaj imie: ";
    do {
        cin.clear();
        cin.ignore( numeric_limits < streamsize >::max(), '\n' );
        cin >> imie;
        if( cin.good() != true )
             cout << "podano nieprawidlowa wartosc!" << endl;
        else
             break;
       
    } while( !cin.good() );
   
    cout << "Podaj nazwisko: ";
    do {
        cin.clear();
        cin.ignore( numeric_limits < streamsize >::max(), '\n' );
        cin >> nazwisko;
        if( cin.good() != true )
             cout << "podano nieprawidlowa wartosc!" << endl;
        else
             break;
       
    } while( !cin.good() );
   
    cout << "Podaj wiek: ";
    do {
        cin.clear();
        cin.ignore( numeric_limits < streamsize >::max(), '\n' );
        cin >> wiek;
        if( cin.good() != true )
             cout << "podano nieprawidlowa wartosc!" << endl;
        else
             break;
       
    } while( !cin.good() );
   
}

void wypiszOsobe( string imie, string nazwisko, int wiek ) {
    cout << "Imie: " << imie << endl << "Nazwisko: " << nazwisko << endl << "Wiek: " << wiek << endl;
}

int main()
{
    string imie[ 2 ];
    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 ] );
   
    system( "pause" );
    return 0;
}

Teraz problemem jest to że program pytając na początku o imie robi to dwa razy i pierwszej wpisanej wartości nie zapisuje nigdzie.Drugim problemem jest to że można wprowadzić liczby do imienia i nazwiska.
P-141102
carlosmay
» 2015-11-29 19:46:54
program pytając na początku o imie robi to dwa razy
 Przed pierwszym wczytywaniem imienia masz czyszczenie pustego strumienia, więc metoda cin.ignore() (a strumień jest pusty) czeka na znak nowego wiersza.
Tak możesz rozwiązać wczytywanie
C/C++
while( !( cin >> imie ) ) { // choc uwazam to za zbedne
    cin.clear();
    cin.ignore( numeric_limits < streamsize >::max(), '\n' );
}
 
Drugim problemem jest to że można wprowadzić liczby do imienia i nazwiska.
 Cóż. Liczby to też znaki alfanumeryczne, ale odwrotnie już nie (litery to nie liczby (pomijam reprezentację liczbową liter - tabela ASCII)).

edit:
Jeśli chcesz zabezpieczyć program przed niepoprawnymi danymi napisz funkcję, która to robi poprawnie.
Np:
C/C++
const char msg[] = { "Write data: " }; // komunikaty wzywane w funkcji GetData()
const char errMsg[] = { "Error data. Once again: " };

template < typename T >
T GetData( const char * message, const char * errmesg ) // uniwersalna funkcja do wczytywania różnego typu danych
{
    bool ctrlErr = true; // flaga dla niepoprawnych danych
    T data;
    do {
        while(( cout << message ) &&( cin >> data ) && ctrlErr ) // jesli poprawnie wykonane wczytywanie nie powtarzaj petli
        {
            ctrlErr = false;
            cin.clear();
            if( cin.get() != '\n' ) {
                cout << errmesg;
                cin.ignore( numeric_limits < streamsize >::max(), '\n' );
                ctrlErr = true;
                continue;
            }
            break;
        }
        if( !cin ) { // jesli pominieto petle, wyczysc bufor i ustaw flage na powtorzenie wczytywania
            ctrlErr = true;
            cin.clear();
            cin.ignore( numeric_limits < streamsize >::max(), '\n' );
        }
    } while( ctrlErr );
   
    return data;
}

void wczytajOsobe( string & imie, string & nazwisko, int & wiek ) {
    cout << "Podaj imie: ";
    imie = GetData < string >( msg, errMsg ); // wczytanie imienia, w < > ustawiamy jakiego typu dane ma obsluzyc funkcja
   
    cout << "Podaj nazwisko: ";
    nazwisko = GetData < string >( msg, errMsg ); // wczytanie nazwiska
   
    cout << "Podaj wiek: ";
    wiek = GetData < int >( msg, errMsg ); // wczytanie wieku
}
 
P-141118
« 1 » 2
  Strona 1 z 2 Następna strona