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

Rozdział 34. Kontrola błędów - Program rozpoznaje wszystkie liczby oprócz jednej!

Ostatnio zmodyfikowano 2017-02-18 13:18
Autor Wiadomość
meoleo
Temat założony przez niniejszego użytkownika
Rozdział 34. Kontrola błędów - Program rozpoznaje wszystkie liczby oprócz jednej!
» 2017-02-17 13:51:36
Witam,

Zacząłem robić kurs C++ i utknąłem na zadaniu z rozdziału 34 na poziomie 4.
Program ma wczytywać z pliku dane, oczyścić je ze znaków i wyświetlić tylko liczby, a następnie je zsumować.
Program działa poprawnie ale z małym wyjątkiem, mianowicie pomija jedną "dwójkę".
Zawartość pliku "LiczbyZadanie.txt" to:
a 1 2 321b9 ac.de ef#@g 5 #3
i właśnie trzeci znak nie jest rozpoznawany jako liczba.

Kod programu:

C/C++
#include <string>
#include <fstream>
#include <iostream>

bool wczytajLiczbe( std::ifstream & plik, int & iLiczba, int & suma )
{
    plik.clear(); //Wyczyszczenie ewentualnych flag b³êdów
    plik >> iLiczba;
    if( plik.bad() )
    {
        std::cout << "Wystapil blad sprzetowy!" << std::endl;
        plik.close();
        return false;
    } else
    if( plik.fail() )
    {
        return false;
    } else
         std::cout << "Liczba: " << iLiczba << std::endl;
   
    suma += iLiczba;
    return true;
}

bool wczytajZnak( std::ifstream & plik, char & cZnak )
{
    plik.clear(); //Wyczyszczenie ewentualnych flag b³êdów
    plik >> cZnak;
    if( plik.bad() )
    {
        std::cout << "Wystapil blad sprzetowy!" << std::endl;
        plik.close();
        return false;
    } else
    if( plik.fail() )
    {
        return false;
    } //if
    std::cout << "Znak:  " << cZnak << std::endl;
    return true;
}

bool odczytajPlik( std::string sNazwaPliku )
{
    std::ifstream plik;
    plik.open( sNazwaPliku.c_str() );
    if( !plik.good() )
    {
        std::cout << "Nie udalo sie otworzyc pliku." << std::endl;
        return false;
    } //if
    int suma = 0;
    while( !plik.eof() )
    {
        int iLiczba;
        char cZnak;
       
        if( !wczytajLiczbe( plik, iLiczba, suma ) && plik.bad() )
             return false; //wczytanie liczby nie powiod³o siê z powodu b³êdu sprzêtowego
        else if( !wczytajZnak( plik, cZnak ) )
        {
            if( plik.bad() )
                 return false; //wczytanie znaku nie powiod³o siê z powodu b³êdu sprzêtowego
            else
                 break; //nie ma wiêcej danych w strumieniu (bo jeden znak zawsze powinno siê daæ odczytaæ)
           
        } //if
    } //while
    plik.close();
    std::cout << std::endl << "Suma liczb wynosi: " << suma << std::endl;
    return true;
}

int main()
{
    if( odczytajPlik( "liczbyZadanie.txt" ) )
         std::cout << "Plik zostal wczytany!" << std::endl;
   
    return 0;
}

Proszę o pomoc.
P-157899
maly7
» 2017-02-17 20:01:27
Spróbuj tak:
C/C++
if( wczytajLiczbe( plik, iLiczba, suma ) ) { }
else if( !wczytajLiczbe( plik, iLiczba, suma ) && plik.bad() )
     return false; //wczytanie liczby nie powiod³o siê z powodu b³êdu sprzêtowego
else if( !wczytajZnak( plik, cZnak ) )
{
    if( plik.bad() )
         return false; //wczytanie znaku nie powiod³o siê z powodu b³êdu sprzêtowego
    else
         break; //nie ma wiêcej danych w strumieniu (bo jeden znak zawsze powinno siê daæ odczytaæ)
   
}
Po za tym:
C/C++
else
     break;
jest niepotrzebne, ponieważ pętla while i tak się zakończy jeśli będzie eof.
P-157913
meoleo
Temat założony przez niniejszego użytkownika
» 2017-02-18 12:31:01
Dzięki działa, choć nie rozumie dlaczego ?
Dodałeś jednego if który nie ma żadnych instrukcji, czy ma to jakiś związek z wywołaniem funkcji "wczytajLiczbe(...)" ?
P-157934
maly7
» 2017-02-18 13:18:43
Pierwszy warunek:
if( !wczytajLiczbe( plik, iLiczba, suma ) && plik.bad() )
 wykona się tylko jeśli nie wczyta liczby i będzie flaga plik.bad(). Jeśli wczyta liczbę to i tak sprawdzi drugi warunek który wczyta kolejną liczbę jako znak. Nawet liczby można wczytać jako znak, więc zawsze się uda wczytać int od char. Dlatego najpierw sprawdź, czy udało się wczytać poprawnie liczbę, jeśli warunek się wykona to przeleci przez wszystkie pozostałe i nie sprawdzi kolejnych 'elsów'.
P-157936
« 1 »
  Strona 1 z 1