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

Błąd w rozdziale 4.34

Ostatnio zmodyfikowano 2016-05-10 18:57
Autor Wiadomość
KrulTibianus
Temat założony przez niniejszego użytkownika
Błąd w rozdziale 4.34
» 2016-05-10 16:22:04
Cześć.
Analizuję przykład podsumowujący rozdział 34. Jeśli w pliku znajduje się np. 5 4 3 2 1, konsola wyświetli prawidłowo tylko co drugą liczbę:
Liczba = 5
Napotkany znak = '4'
Liczba = 3
Napotkany znak = '2'
Liczba = 1

Przy liczbach np. 10 33 konsola wyświetli:
Liczba = 10
Napotkany znak = '3'
Liczba = 3

Próbuję doszukać się błędu, który to powoduje, ale go nie widzę... Poniżej kod.

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

bool wczytajLiczbe( std::ifstream & plik, int & iLiczba )
{
    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() )
    {
        std::cout << "Nie udalo sie wczytac liczby!" << std::endl;
        return false;
    } else
         std::cout << "Liczba = " << iLiczba << std::endl;
   
    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() )
    {
        std::cout << "Nie udalo sie wczytac znaku!" << std::endl;
        return false;
    } //if
    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
    while( !plik.eof() )
    {
        int iLiczba;
        char cZnak;
       
        if( !wczytajLiczbe( plik, iLiczba ) && 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
        std::cout << "Napotkany znak = '" << cZnak << "'" << std::endl;
    } //while
    plik.close();
    return true;
}

int main()
{
    if( odczytajPlik( "cpp0x.txt" ) )
         std::cout << "Plik zostal wczytany!" << std::endl;
   
    return 0;
}
P-148081
carlosmay
» 2016-05-10 16:33:09
Operator
>>
 pomija poprzedzające znaki odstępu (nie są brane pod uwagę).
P-148082
KrulTibianus
Temat założony przez niniejszego użytkownika
» 2016-05-10 17:02:17
Nie bardzo wiem, co z tym zrobić. W zadaniu domowym będę potrzebował, aby odczytywało mi liczby oddzielone spacją. Nie będę mógł zatem używać operatora >>?
P-148084
carlosmay
» 2016-05-10 17:29:29
Nie będę mógł zatem używać operatora >>?
Możesz.
Zmienna
char
 jest niepotrzebna, bo spacja jest pomijana.
Wczytuj same liczby.

C/C++
{
    int a, b, c;
    file >> a >> b >> c; // wczytanie trzech liczb oddzielonych spacjami

Edit:
Co do wczytywania z pliku: Należy sposób wczytywania dopasować do zawartości i typu pliku, lub wczytać wszystkie dane i później wykonać na nich operacje.
P-148085
KrulTibianus
Temat założony przez niniejszego użytkownika
» 2016-05-10 18:57:00
Dobra, poradziłem sobie. W zadaniu poprzednim było wczytywanie z pliku, w którym były tylko liczby - łatwizna. W tym dodatkowo były inne znaki, które należało pominąć. "Napisz program, który wczyta z pliku liczby całkowite i wypisze je na ekranie. Wszelkie nieprawidłowe znaki mają zostać pominięte. Program ma wypisać również sumę wszystkich wczytanych liczb. "

Poradziłem sobie taką pętlą:
C/C++
while( !plik.eof() )
{
    int liczba;
    char znak;
    plik >> liczba;
    if( plik.bad() )
    {
        std::cout << "Wystapil blad sprzetowy!" << std::endl;
        plik.close();
        return 0;
    } else
    if( plik.fail() )
    {
        plik.clear();
        plik >> znak;
        if( plik.bad() )
        {
            std::cout << "Wystapil blad sprzetowy przy wczytywaniu znaku" << std::endl;
            plik.close();
            return 0;
        } else
        if( plik.fail() )
        {
            plik.clear();
            break;
        }
    } else
    {
        std::cout << liczba << " ";
        wynik += liczba;
    }
}
P-148089
« 1 »
  Strona 1 z 1