Mateus. Temat założony przez niniejszego użytkownika |
Lekcja 34 - zadanie 2. » 2014-06-26 11:55:19 Drugi raz mam problem. Polecenie: 2. [trudne zadanie] Napisz program, który dla każdego wiersza w pliku: •wczyta liczby i wypisze ich sumę w przypadku, gdy wszystkie liczby uda się wczytać; •wypisze komunikat o błędnych danych, jeżeli wystąpi błąd podczas wczytywania liczb (komunikat ma wyświetlać numer wiersza, w którym wystąpił błąd). Przykładowe dane: 1 2 3 3 4 a 5 3 2 5 2 2 1 3 # 3 4
Oczekiwane standardowe wyjście programu dla przykładowego zestawu danych: 6 Bledne dane w wierszu nr 2! 5 13 Bledne dane w wierszu nr 5!
Wykorzystaj poniższą funkcję do wykrywania znaku przejścia do nowej linii: bool czyNapotkanoZnakNowegoWiersza( std::ifstream & plik ) { char cZnak; for(;; ) { plik.clear(); cZnak = plik.peek(); if( plik.fail() || plik.bad() ) return false; if( !isspace( cZnak ) ) return false; plik.get( cZnak ); if( plik.fail() || plik.bad() ) return false; if( cZnak == '\n' ) return true; } }
Powyższej funkcji nie wolno modyfikować. Mój kod - trochę się go wstydzę, bo moim zdaniem jest głupi :-) #include <string> #include <fstream> #include <iostream> using namespace std; bool czy( ifstream & plik ) { char cZnak; for(;; ) { plik.clear(); cZnak = plik.peek(); if( plik.fail() || plik.bad() ) return false; if( !isspace( cZnak ) ) return false; plik.get( cZnak ); if( plik.fail() || plik.bad() ) return false; if( cZnak == '\n' ) return true; } } void funkcja( string sciezka ) { ifstream plik; string wiersz; plik.open( sciezka.c_str() ); int a; int i = 1; int suma = 0; while( !plik.eof() ) { plik >> a; suma += a; if( czy( plik ) == false ) { cout << "Napotkano blad w wierszu nr. " << i << endl; plik.clear(); char b; plik >> b; } else if( czy( plik ) == true ) { cout << suma << endl; } i++; } plik.close(); } int main() { funkcja( "C://Users//Mateusz//Documents//plik.txt" ); return 0; }
Wynik działania (albo raczej nie działania) programu: Napotkano blad w wierszu nr. 1 Napotkano blad w wierszu nr. 3 Napotkano blad w wierszu nr. 4 Napotkano blad w wierszu nr. 6 Napotkano blad w wierszu nr. 7 Napotkano blad w wierszu nr. 8 Napotkano blad w wierszu nr. 10 Napotkano blad w wierszu nr. 11 Napotkano blad w wierszu nr. 12
Moim problemem jest to, że nie wiem do czego wykorzystać tą narzuconą z góry funkcję. Proszę o jakieś wskazówki/podpowiedzi. |
|
Jacob99 |
» 2014-06-26 12:01:23 Ile razy już było pisane na forum, żeby nie używać tej konstrukcji while( !plik.eof() ) . Zamiast niej powinno być while( plik >> a ) I nigdzie w tej funkcji nie używasz string wiersz; |
|
Mateus. Temat założony przez niniejszego użytkownika |
» 2014-06-26 12:16:40 Ja w kursie nie widziałem nigdy takiego warunku, a sam na niego nie wpadłem. Tylko, że dalej nie wiem co zrobić z tą funkcją :( |
|
pekfos |
» 2014-06-26 12:17:25 Ile razy już było pisane na forum, żeby nie używać tej konstrukcji while( !plik.eof() ) . |
Żeby jej nigdy nie używać? Ani razu. Nie licząc informacji powtarzanych bez zrozumienia. |
|
Mateus. Temat założony przez niniejszego użytkownika |
» 2014-06-26 12:26:14 string wiersz to pozostałość po jednej (przeoczyłem to) z poprzednich prób, gdzie używałem takiej pętli while( getline( plik, wiersz ) ) { } , ale tez nic mi z tego nie wyszło :( Czekam na jakieś porady :D |
|
pekfos |
» 2014-06-26 12:39:09 if( czy( plik ) == false ) { cout << "Napotkano blad w wierszu nr. " << i << endl; plik.clear(); char b; plik >> b; } else if( czy( plik ) == true ) { cout << suma << endl; } i++;
|
Gdy czy() zwraca false, nie oznacza to błędu. Błąd musisz określić na podstawie stanu strumienia plik zaraz po operacji. Dodatkowo, drugi if jest niepotrzebny, wystarczy samo else. Wtedy nie będzie dodatkowego wywołania czy() które zepsuje wszystko. i musisz inkrementować raz na jedną linię, a nie wczytaną wartość. W tym samym miejscu musisz też wyzerować suma (po jej wypisaniu). |
|
Mateus. Temat założony przez niniejszego użytkownika |
» 2014-06-26 12:43:05 Ok. Dzięki za odpowiedź. Teraz muszę wyjść z domu. Dam znać po południu czy mi się udało :-) |
|
Mateus. Temat założony przez niniejszego użytkownika |
» 2014-06-26 16:42:57 Napisałem to wszystko (kilkakrotnie próbowałem) od nowa i przeanalizowałem tą funkcję bool czy( ifstream & plik ) i chociaż zrozumiałem (tak mi się wydaje) jej działanie, oraz do czego służy, to mój program działa tylko na dwa pierwsze wiersze pliku :( Kod: #include <string> #include <fstream> #include <iostream> using namespace std; bool czy( ifstream & plik ) { char cZnak; for(;; ) { plik.clear(); cZnak = plik.peek(); if( plik.fail() || plik.bad() ) return false; if( !isspace( cZnak ) ) return false; plik.get( cZnak ); if( plik.fail() || plik.bad() ) return false; if( cZnak == '\n' ) return true; } } void funkcja( string sciezka ) { ifstream plik; plik.open( sciezka.c_str() ); float a; float i = 1; float suma; while( !plik.eof() ) { suma = 0; while( czy( plik ) != true ) { plik >> a; if( plik.fail() ) { cout << "Bledne dane w wierszu nr. " << i << endl; plik.clear(); char b; plik >> b; break; } else { suma += a; } } i++; cout << "Suma wynosi: " << suma << endl; } } int main() { funkcja( "C://Users//Mateusz//Documents//plik.txt" ); return 0; }
Suma wynosi: 6 Bledne dane w wierszu nr. 2 Suma wynosi: 7 Suma wynosi: 5 Suma wynosi: 5 Suma wynosi: 13 Bledne dane w wierszu nr. 6 Suma wynosi: 0 Bledne dane w wierszu nr. 7 Suma wynosi: 7
Teraz to już nie wiem co robię źle (chociaż przypuszczam, że błąd jest w warunkach pętli). Gdy zmieniam warunek w zewnętrznej pętli na while( plik >> a ) to otrzymuje takie cudo: Suma wynosi: 5 Bledne dane w wierszu nr. 2 Suma wynosi: 4 Suma wynosi: 0 Suma wynosi: 2 Suma wynosi: 8
Pomożecie? :D |
|
« 1 » 2 3 |