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

Wczytywanie danych z pliku inFile >>

Ostatnio zmodyfikowano 2014-04-27 22:33
Autor Wiadomość
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 :(.

C/C++
#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.
P-108639
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.
C/C++
...
( 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();
 
P-108642
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 :)
P-108643
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.
P-108656
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 :)

C/C++
#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
P-108661
michal11
» 2014-04-25 23:36:00
@Jacob99

czy mógłbyś napisać dlaczego nigdy nie używać dynamicznej alokacji w maine ?
P-108699
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?
P-108702
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...
P-108725
« 1 » 2
  Strona 1 z 2 Następna strona