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

rozdzial/lekcja 34, zadanie nr 2

Ostatnio zmodyfikowano 2022-04-22 20:46
Autor Wiadomość
jebackoze
Temat założony przez niniejszego użytkownika
rozdzial/lekcja 34, zadanie nr 2
» 2022-04-21 21:49:21
popelnilem kod (zmodyfikowalem ten z przykladu w lekcji) i dziala, ale czy nie ustrzeglem sie jakiegos bledu? zadanie opisane jako trudne wiec pewnie jakies pulapki byly

EDYCJA: chyba jednak popelnilem jakis blad bo nie wczytuje ostatniego wiersza jesli dodam kolejne wiersze z liczbami do pliku tekstowego

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

bool czyEnter( std::ifstream & plik )
{
   
char cZnak;
   
for(;; ) //nieskończona pętla
   
{
       
plik.clear();
       
cZnak = plik.peek(); //sprawdzamy jaki kolejny znak zostanie zwrócony przez operację odczytu
       
if( plik.fail() )
           
 return false; //wystąpił błąd odczytu danych
       
       
if( !isspace( cZnak ) )
           
 return false; //pobrany znak nie jest białym znakiem
       
       
plik.get( cZnak ); //odczytujemy biały znak z pliku
       
if( plik.fail() )
           
 return false; //wystąpił błąd odczytu danych
       
       
if( cZnak == '\n' )
           
 return true;
       
   
} //for
} // koniec szablonu

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, wiersz = 1;
   
while( true )
   
{
       
int iLiczba;
       
char cZnak;
       
       
plik >> iLiczba;
       
       
if( !plik.fail() )
       
{
           
suma += iLiczba;
           
if( czyEnter( plik ) )
           
{
               
std::cout << "suma: " << suma << std::endl;
               
++wiersz;
               
suma = 0;
           
}
        }
       
else
       
{
           
           
if( plik.bad() )
               
 return false; //wczytanie liczby nie powiodło się z powodu poważnego błędu
           
           
plik.clear();
           
plik >> cZnak;
           
           
if( !plik.fail() )
           
{
               
std::cout << "blad w wierszu nr " << wiersz << std::endl;
               
suma = 0;
               
++wiersz;
               
plik.clear();
               
plik.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );
               
           
}
           
else
           
{
               
if( plik.eof() )
                   
 break;
               
               
return false; // wczytanie znaku powinno zawsze się udać, chyba że skończyły się dane
           
} //if
       
} //if
   
} //while
   
   
std::cout << "Koniec pliku" << std::endl;
   
return true;
}


int main()
{
   
if( odczytajPlik( "34.2.txt" ) )
       
 std::cout << "Plik zostal poprawnie wczytany!" << std::endl;
   
   
return 0;
}
P-179419
pekfos
» 2022-04-22 17:39:42
Ten kod zakłada pustą linię na końcu pliku.
P-179421
jebackoze
Temat założony przez niniejszego użytkownika
» 2022-04-22 17:57:00
powinienem cos dopisac, czy raczej zmodyfikowac (rozumiem, ze gdzies w rejonie
if( czyEnter( plik ) )
 cos mi sie krzaczy)?

EDYCJA, chyba mam to (omylkowo wkleilem inna wersje kodu wczesniej):
C/C++
#include <iostream>
#include <fstream>
#include <string>
#include <limits>

bool czyEnter( std::ifstream & plik )
{
   
char cZnak;
   
for(;; ) //nieskończona pętla
   
{
       
plik.clear();
       
cZnak = plik.peek(); //sprawdzamy jaki kolejny znak zostanie zwrócony przez operację odczytu
       
if( plik.fail() )
           
 return false; //wystąpił błąd odczytu danych
       
       
if( !isspace( cZnak ) )
           
 return false; //pobrany znak nie jest białym znakiem
       
       
plik.get( cZnak ); //odczytujemy biały znak z pliku
       
if( plik.fail() )
           
 return false; //wystąpił błąd odczytu danych
       
       
if( cZnak == '\n' )
           
 return true;
       
   
} //for
} // koniec szablonu

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, wiersz = 1;
   
while( true )
   
{
       
int iLiczba;
       
char cZnak;
       
       
plik >> iLiczba;
       
       
if( !plik.fail() )
       
{
           
suma += iLiczba;
           
if( czyEnter( plik ) )
           
{
               
std::cout << "suma: " << suma << std::endl;
               
++wiersz;
               
suma = 0;
           
}
           
if( !czyEnter( plik ) && plik.eof() ) // dopisane wzgledem 1-szego kodu
               
 std::cout << "suma: " << suma << std::endl; // dopisane wzgledem 1-szego kodu
           
       
}
       
else
       
{
           
           
if( plik.bad() )
               
 return false; //wczytanie liczby nie powiodło się z powodu poważnego błędu
           
           
plik.clear();
           
plik >> cZnak;
           
           
if( !plik.fail() )
           
{
               
std::cout << "blad w wierszu nr " << wiersz << std::endl;
               
suma = 0;
               
++wiersz;
               
plik.clear();
               
plik.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );
           
}
           
else
           
{
               
if( plik.eof() )
                   
 break;
               
               
return false; // wczytanie znaku powinno zawsze się udać, chyba że skończyły się dane
           
} //if
       
} //if
   
} //while
   
   
std::cout << "Koniec pliku" << std::endl;
   
return true;
}

int main()
{
   
if( odczytajPlik( "34.2.txt" ) )
       
 std::cout << "Plik zostal poprawnie wczytany!" << std::endl;
   
   
return 0;
}
P-179423
pekfos
» 2022-04-22 19:04:25
To nie jest poprawne rozwiązanie, bo czyEnter() ma efekty uboczne. 2 razy sprawdzasz zwracaną wartość więc są tam 2 wywołania. Będzie błędnie liczyć linie jeśli masz w pliku sekwencję znaków nowej linii.

W sumie to jeśli dopuszczamy puste linie, trzeba kod bardziej zmodyfikować by liczył je dobrze.
P-179425
jebackoze
Temat założony przez niniejszego użytkownika
» 2022-04-22 20:46:11
chyba musze tutaj przycupnac na dluzej bo nie mam na razie planu jak uporac sie z sekwencja pustych linii.
myslalem, ze ten szablon kodu, ktory jest opisany jako
Wykorzystaj poniższą funkcję do wykrywania znaku przejścia do nowej linii

zalatwi sprawe
P-179426
« 1 »
  Strona 1 z 1