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

Wczytywanie danych z pliku

Ostatnio zmodyfikowano 2017-08-13 13:54
Autor Wiadomość
jankowalski25
» 2017-08-11 16:54:03
Metoda
good()
 zwróci
false
 po osiągnięciu końca pliku (nawet jeśli dane były poprawne), dlatego lepiej zanegować wartość zwróconą przez
fail()
.
P-163916
bartinio07
Temat założony przez niniejszego użytkownika
» 2017-08-12 00:57:49
Ok, dzięki za pomoc. Mam jednak jeszcze problem z kodem z kolejnej lekcji:
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;
}
Zawartość pliku tekstowego to:
--==[ Kurs C++ | http://cpp0x.pl ]==--
Obecnie uczysz sie obslugi plikow. Link do czytanego rozdzialu:
http://cpp0x.pl/kursy/Kurs-C++/Poziom-4/Wczytywanie-tekstu-z-pliku/355
Udalo Ci sie odczytac plik?

Wykonaj teraz prace domowa ze wspomnianego rozdzialu! :)
Fragment działania programu:
Napotkany znak: t
Nie udalo sie wczytac liczby!
Napotkany znak: a
Nie udalo sie wczytac liczby!
Napotkany znak: n
Nie udalo sie wczytac liczby!
Napotkany znak: e
Nie udalo sie wczytac liczby!
Napotkany znak: g
Nie udalo sie wczytac liczby!
Napotkany znak: o
Nie udalo sie wczytac liczby!
Napotkany znak: r
Nie udalo sie wczytac liczby!
Napotkany znak: o
Nie udalo sie wczytac liczby!
Napotkany znak: z
Nie udalo sie wczytac liczby!
Napotkany znak: d
Nie udalo sie wczytac liczby!
Napotkany znak: z
Nie udalo sie wczytac liczby!
Napotkany znak: i
Nie udalo sie wczytac liczby!
Napotkany znak: a
Nie udalo sie wczytac liczby!
Napotkany znak: l
Nie udalo sie wczytac liczby!
Napotkany znak: u
Nie udalo sie wczytac liczby!
Napotkany znak: :
 Dlaczego program pomija pierwsza linijkę i fragment drugiej? Dalej odczytuje już dobrze, ale moe wklejałem już całego wyniku, bo jest on dość długi. Poza tym nie bardzo rozumiem ten fragment kodu:
C/C++
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ć)
   
Sprawdzanie, czy wczytanie liczby albo znaku z powodu błędu sprzętowego było już w dwóch poprzednich funkcjach, więc dlaczego tutaj jest jeszcze raz?
P-163928
karambaHZP
» 2017-08-12 09:03:53
Jeśli nie rozumiesz jakiegoś fragmentu

Co do okrojonych wyników. możesz mieć za małą wysokość bufora konsoli i pierwsze wyniki wyjeżdżają z niej.
Nie są widoczne.
P-163929
bartinio07
Temat założony przez niniejszego użytkownika
» 2017-08-12 15:44:44
Faktycznie, przy krótszym tekście wczytuje całość. Co do filmiku, to rozumiem, że jest to sposób do szukania błędu, gdy aplikacja nie działa poprawnie. W moim przypadku wszystko działa, tylko nie potrafiłbym wytłumaczyć, co robi ten fragment programu.
P-163933
karambaHZP
» 2017-08-12 21:23:47
Co do filmiku, to rozumiem, że jest to sposób do szukania błędu, gdy aplikacja nie działa poprawnie.
Gdy działa poprawnie również jest przydatną metodą. Szukanie błędów i próby zrozumienia cudzego kodu, aż tak
bardzo nie różnią się do siebie. Spróbuj samemu. Lepszy będzie efekt.
P-163939
bartinio07
Temat założony przez niniejszego użytkownika
» 2017-08-13 13:54:24
Ja to rozumiem tak:
C/C++
if( !wczytajLiczbe( plik, iLiczba ) && plik.bad() )
     return false;

 Jeśli funkcja
wczytajLiczbe
 zwróci wartość
false
 i metoda
bad
 zwróci wartość
true
, czyli wystąpił błąd sprzętowy, to funkcja
odczytajPlik
 zwróci wartość
false
.
C/C++
else
if( !wczytajZnak( plik, cZnak ) )
{
    if( plik.bad() )
         return false;
    else
         break;
   
}
W przeciwnym wypadku analogicznie z funkcją
wczytajZnak
.
Pewnie coś źle zrozumiałem, ale skoro funkcje
wczytajLiczbe
 i
wczytajZnak
 zwracają fałsz m.in. wtedy, gdy wystąpił błąd sprzętowy, to dlaczego nie wystarczy zapis
if( !wczytajLiczbe( plik, iLiczba ) )
 i
if( !wczytajZnak( plik, cZnak ) )
?
P-163947
1 « 2 »
Poprzednia strona Strona 2 z 2