Wczytywanie danych z pliku inFile >>
Ostatnio zmodyfikowano 2014-04-27 22:33
Wojtekg Temat założony przez niniejszego użytkownika |
Wczytywanie danych z pliku inFile >> » 2014-04-25 10:18:50 Witam Napotkałem na swojej drodze mały problem. Otóż przerabiałem program który wczytywał dane podawane przez użytkownika na taki aby pobierał danę z pliku tekstowego program działa dobrze do momentu pobrania pierwszego obiektu string. Pobiera on samo imię i się sypie. Próbowałem działać tutaj funkcją getline lecz niestety bezskutecznie. Funkcja cin.ignore() działa chyba tylko przy wczytywaniu znaków z klawiatury więc też odpada. Niżej podaję kod. Dodam że gdy program wczytuje same imiona działa dobrze, niestety jest problem z wczytaniem całej linii :(. #include <iostream> #include <fstream> #include <cstdlib>
using namespace std; struct donatorzy { string imie; double kwota; };
int main() { std::ifstream inFile; char filename[ 100 ]; cout << "Podaj nazwe pliku z ktorego maja byc wczytywane dane: "; cin.getline( filename, 100 ); inFile.open( filename ); if( !inFile.is_open() ) { cout << "Nie wczytano pliku."; cout << "Program zostanie zamkniety. "; exit( EXIT_FAILURE ); } int ilosc; cout << "Podaj ilosc sponsorow: " << endl; inFile >> ilosc; donatorzy * p = new donatorzy[ ilosc ]; for( int i = 0; i < ilosc; i++ ) { cout << "Podaj imie sponsora: " << endl; cin.sync(); inFile >>( cin, p[ i ].imie ); cout << "Podaj kwote jaka wplacil sponsor: " << endl; inFile >> p[ i ].kwota; } if( inFile.eof() ) { cout << "koniec pliku." << endl; } else if( inFile.fail() ) { cout << "Przerwano wczytywanie pliku - blad\n"; }; cout << "Nasi wspaniali sponsorzy: " << endl; for( int i = 0; i < ilosc; i++ ) { if( p[ i ].kwota >= 10000 ) cout << p[ i ].imie << endl; }; cout << "Nasi sponsorzy: " << endl; for( int i = 0; i < ilosc; i++ ) { if( p[ i ].kwota < 10000 ) cout << p[ i ].imie << endl; } delete[] p; return 0; }
Plik tekstowy do wczytania wygląda tak: "4 Sam Stone 2000 Freida Flass 100500 Tammy Tubbs 5000 Rich Raptor 55000" No i wiadomo że po przerobieniu programu usunę niepotrzebne wyświetlenia linijek w pętli for bo są tutaj całkowicie zbędne :) Czekam na jakieś podpowiedzi. Pozdrawiam Wojtek. |
|
alixir |
» 2014-04-25 10:54:00 Coś słabo próbowałeś z getline. Ogólnie program jak i podejście są kiepskie, ale pomijam już ten fakt. W strumieniu pozostawiasz znak nowej linii i to powodowało problem z getline. ... ( inFile >> ilosc ).get(); ... cout << "Podaj imie sponsora: " << endl; getline( inFile, p[ i ].imie ); cout << "Podaj kwote jaka wplacil sponsor: " << endl; ( inFile >> p[ i ].kwota ).get(); |
|
Wojtekg Temat założony przez niniejszego użytkownika |
» 2014-04-25 11:46:17 Z chęcią posłucham wskazówek co należałoby poprawić w tym programie :) To jest w sumie dopiero początek mojej drogi z programowaniem więc każde wytykanie błędów jak najbardziej byłoby pomocne :) |
|
michal11 |
» 2014-04-25 15:29:37 Nie wczytywałem się dokładnie, ale postaraj się inaczej nazywać zmienne, tak aby było wiadomo o co chodzi bez przewijania kodu. |
|
Jacob99 |
» 2014-04-25 16:29:37 Po pierwsze: tablice znaków nie są dobrym sposobem na przechowywanie danych. Z twojego kodu wnioskuję, że znasz kontener std::string, więc go użyj. Po drugie: funkcja is_open() w if'ie jest zbędna i tylko marnuje zasoby. Po trzecie: Nigdy nie używaj pamięci dynamicznej w funkcji głównej!!! Zamiast tego użyj vectora z biblioteki standardowej. Po czwarte: komentarze!!! Ja nie wiem co chciałeś osiągnąć tym zapisem: inFile >>( cin, p[ i ].imie ); To na razie wszystko. Dodaję jeszcze kod wg. mojego planu :) #include <iostream> #include <fstream> #include <cstdlib> #include <vector> using namespace std; struct donatorzy { string imie; double kwota; }; inline bool cmp( donatorzy & cmp1, donatorzy & cmp2 ) { return cmp1.kwota > cmp2.kwota; }
int main() { ifstream inFile; string filename; cout << "Podaj nazwe pliku z ktorego maja byc wczytywane dane: "; getline( cin, filename ); inFile.open( filename.c_str() ); if( !inFile ) { cout << "Nie wczytano pliku."; cout << "Program zostanie zamkniety. "; exit( EXIT_FAILURE ); } int ilosc; cout << "Podaj ilosc sponsorow: " << endl; inFile >> ilosc; vector < donatorzy > v( ilosc ); for( int i = 0; i < ilosc; i++ ) { cout << "Podaj imie sponsora: " << endl; cin.clear(); getline( inFile, v[ i ].imie, '|' ); cout << "Podaj kwote jaka wplacil sponsor: " << endl; inFile >> v[ i ].kwota; } if( inFile.eof() ) { cout << "koniec pliku." << endl; } else if( inFile.fail() ) { cout << "Przerwano wczytywanie pliku - blad\n"; }; cout << "Nasi wspaniali sponsorzy: " << endl; for( int i = 0; i < ilosc; i++ ) { cout << v[ i ].imie << endl; } return 0; }
Plik do wczytywania wygląda tak 14 //liczba Johann Sebastian Bach| // imię i nazwisko sponsora i znacznik '|' 12000 // kwota wpłacona przez sponsora Janina Lolowska| // imię i nazwisko sponsora i znacznik '|' 3780 // kwota wpłacona przez sponsora |
|
michal11 |
» 2014-04-25 23:36:00 @Jacob99
czy mógłbyś napisać dlaczego nigdy nie używać dynamicznej alokacji w maine ? |
|
Wojtekg Temat założony przez niniejszego użytkownika |
» 2014-04-26 01:41:53 Dzięki wielkie za wskazówki ale tak jak wyżej kolega spytał już. Dlaczego nie używać dynamicznej alokacji w mainie? |
|
Jacob99 |
» 2014-04-26 12:38:24 Dynamiczna alokacja pamięci w funkcji głównej jest niebezpieczna zwłaszcza w dużych programach z kilku powodów: 1. Zajmowanie zbyt dużej ilości pamięci(zwłaszcza przy operowaniu dużymi tablicami), może to doprowadzić do błędu typu out_of_range. 2. Przypadkowe usunięcie wskaźnika przed dealokacją pamięci spowoduje wyciek pamięci. 3. Przypadkowa zmiana wskaźnika na jakiś inny obiekt powoduje wyciek pamięci. 4. Dwukrotne skasowanie tego samego wskaźnika operatorem delete (lub delete[]) jeśli ten wskaźnik nie jest wskaźnikiem zerowym prawdopodobnie spowoduje katastrofę w postaci zniszczenia jakichś danych, które są w pamięci pokazywanej przez wskaźnik. 5. itd... |
|
« 1 » 2 |