Szkaplerny Temat założony przez niniejszego użytkownika |
Niezrozumiałe działanie metody good() przy użyciu operatora >> (wczytywaine danych z pliku) » 2016-07-04 00:43:40 Popełniłem taki oto kod: #include <string> #include <fstream> #include <iostream> using namespace std;
void czytajPlik( ifstream & plik ) { int suma { }; int liczba; while( true ) { if( plik.good() ) { plik >> liczba; cout << "Udalo sie wczytac liczbe: " << liczba << endl; suma += liczba; } else { cout << liczba << endl; break; } } cout << "Suma to: " << suma << endl; }
int main() { ifstream plik; plik.open( "C:\\Users\\TS\\Desktop\\Cpp\\cpp0x\\P4R33\\operatory\\operator\\liczby.txt" ); czytajPlik( plik ); plik.close(); return 0; }
I w takiej formie działa poprawnie. Nie rozumiem jednak, dlaczego wczytuje poprawnie wszystkie liczby. Zmieniając formę w przy pętli while(true) na taką: while( true ) { plik >> liczba; if( plik.good() ) { cout << "Udalo sie wczytac liczbe: " << liczba << endl; suma += liczba; } else { cout << liczba << endl; break; }
Program nie czyta ostatniej liczby, jeżeli jest to ostatni(e) znak(i) w pliku. Czy mógłby ktoś wytłumaczyć działanie metody .good() w tym przypadku? Starałem się przeanalizować zachowanie kompilatora krok po kroku, jednak wciąż to rozwiązanie do mnie nie przemawia. |
|
mateczek |
» 2016-07-04 06:18:49 1. Stan strumienia sprawdzasz po wczytaniu liczby a nie przed. Formuła while(plik>>liczba) załatwia sprawę bo wczytuje liczbę i bada stan strumienia po wykonaniu funkcji 2. Nie ma sensu pracować na liczbie gdy nie udało się jej poprawnie wczytać, Bo sam nie wiem co wówczas jest w tej zmiennej(uwaga do twoich gałęzi else). zobacz poniżej poprawiony kod. #include<iostream> #include<fstream> #include<string> using namespace std;
void czytajPlik( string path ) { int suma = 0, liczba; ifstream plik( path ); if( !plik ) { cout << "zła ścieżka do pliku"; return; } while( plik >> liczba ) { cout << "Udalo sie wczytac liczbe: " << liczba << endl; suma += liczba; } cout << "Suma to: " << suma << endl; }
int main() { czytajPlik( "liczby.txt" ); return 0; }
|
|
Szkaplerny Temat założony przez niniejszego użytkownika |
» 2016-07-04 10:16:32 Właśnie, w przykładzie drugim najpierw wczytuję liczbę do zmiennej liczba, a następnie sprawdzam poprawność wczytania. Pomimo tego taki zapis nie działa poprawnie. W pierwszym (działającym) najpierw sprawdzam poprawność, a dopiero potem wpisuje liczbę. Tego nie rozumiem. Co do else - zapomniałem tego usunąć przed wstawieniem tutaj, chciałem zobaczyć co się wczytuje do zmiennej, gdy jest błąd. I wyświetla wtedy również ostatnią w pliku liczbę, i ona jest wczytywana do zmiennej jako goła liczba (bez newline etc). Chodzi mi o to, że ten drugi sposób wydaje się być poprawnym, a tak nie jest. Pewnie i tak wykorzystam Twój sposób sprawdzania warunku w while, ale chodzi mi o czystą teorię, dlaczego to nie działa. |
|
carlosmay |
» 2016-07-04 11:32:35 Pomimo tego taki zapis nie działa poprawnie. |
Bo za ostatnią liczbą nie ma białego znaku, tylko znak końca pliku, który ustawia strumień dla metody good() na false (uniemożliwia to czytanie poza plikiem). Dodanie w pliku spacji bądź entera na koniec pliku naprawi ten "problem". Używasz niepoprawnej kolejności działań. |
|
Szkaplerny Temat założony przez niniejszego użytkownika |
» 2016-07-04 12:21:25 O, dzięki wielkie! O to mi właśnie chodziło. Czy w takim razie ten pierwszy (działający) kod ma jakieś luki pod względem tego warunku? Czy może dojść do sytuacji, gdzie jakaś liczba nie zostanie wczytana? |
|
carlosmay |
» 2016-07-04 14:08:27 Czy w takim razie ten pierwszy (działający) kod ma jakieś luki pod względem tego warunku? |
Ma luki. Punkt 2 @mateczek. Jeśli niepowodzenie ma miejsce w pierwszym cyklu pętli, zmienna ma wartość nieokreśloną. W każdym kolejnym pozostaje niezmieniona z poprzedniego cyklu. Rozwiązanie @mateczek jest najsensowniejsze. |
|
Szkaplerny Temat założony przez niniejszego użytkownika |
» 2016-07-04 15:43:15 I na takie też zmieniłem, dzięki wielkie za pomoc. |
|
« 1 » |