• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Język C++ szkoła programowania - rozdział 6 zadanie 9, wprowadzanie danych z pliku do tablicy struktur.

VPS Starter Arubacloud
0 głosów
305 wizyt
pytanie zadane 24 maja 2018 w C i C++ przez Junior_plusplus Obywatel (1,130 p.)

Treść Zadania 9 z rozdziału 6:

"Ponownie wykonaj ćwiczenie 6 ale tym razem informacje mają być odczytywane z pliku. Pierwszy zapis w pliku to liczba donatorów dalej wiersze są ułożone parami: pierwszy wiersz pary zawiera nazwisko darczyńcy, drugi zawiera wysokość wpłaty"
4
Sam Stone
10000
Freida Flass
10050
Tammy Tubbs
5000
Rich Raptor
55000


Treść zadania 6 : 
"Przygotuj program śledzący wpływy na konto Towarzystwa na Rzecz Zachowania Dobrych Wpływów. Użytkownik ma być pytany o liczbę wpłacających, a następnie ma prosić o podanie wpłaty każdego donatora. Informacje należy umieścić w dynamicznie alokowanej tablicy struktur. Każda struktura ma mieć dwa pola: tablice znakowa (lub obiekt klasy string) na nazwisko oraz pole typu double na kwotę. Po odczytaniu wszystkich danych program ma pokazać nazwiska i wpłaty wszystkich, którzy dali przynajmniej 10000. Lista ta ma mieć nagłówek Nasi Wspaniali Sponsorzy. Dalej program ma pokazać listę pozostałych ofiarodawców, tym razem z nagłówkiem Nasi Sponsorzy".

Witam, mam problem, który polega na tym, że podczas uruchomienia programu wyświetlana jest tylko pierwsza z wczytanych z pliku osób wraz z wysokością datku. Dodam, że instrukcje sprawdzające wskazują na błąd z odczytem danych który zostaje przerwany.

W związku z powyższym bardzo proszę o:

- pomoc/wskazówkę  w rozwiązaniu problemu,

- ogólną ocenę kodu/wskazówki co mógłbym ulepszyć.

Z góry dziękuję za pomoc.

Poniżej kod:

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <sstream>

using namespace std;

struct ofiarodawcy
{
    string nazwisko;
    double wysokosc_datku;
};

int main()
{
    char nazwa_pliku[30];
    ifstream odczyt;

    cout << "Witaj! Prosze podaj nazwe pliku ktory chcesz wczytac: ";
    cin.getline(nazwa_pliku, 30);
    cout << endl;
    odczyt.open(nazwa_pliku);

    if (!odczyt.is_open())
     {
        cout << "Otwarcie pliku " << nazwa_pliku << " nie powiodlo sie.\n";
        cout << "Program zostanie zakonczony.\n";
        exit (EXIT_FAILURE);
    }
    string ilosc_darczyncow_konwersja;
    getline(odczyt,ilosc_darczyncow_konwersja);

    int ilosc_darczyncow;
    istringstream is(ilosc_darczyncow_konwersja);
    is>>ilosc_darczyncow;

    ofiarodawcy * baza_darczyncow = new ofiarodawcy[ilosc_darczyncow];

    for (int i = 0; i < ilosc_darczyncow; i++)
    {
        getline(odczyt, baza_darczyncow[i].nazwisko);
        odczyt>>baza_darczyncow[i].wysokosc_datku;
    }
     if (odczyt.eof())
        cout << "\n\nKoniec pliku.\n";
    else if (odczyt.fail())
        cout << "Wczytywanie danych przerwane - blad.\n";
    else
        cout << "Wczytywanie danych przerwane, przyczyna nieznana.\n";
    if (ilosc_darczyncow == 0)
        cout << "Nie przetworzono zadnych danych.\n";
    else
    {
        int ilosc_osob = 0;

        cout << "Nasi Wspaniali Sponsorzy: \n";
        for (int i = 0; i < ilosc_darczyncow; i++)
        {
             if(baza_darczyncow[i].wysokosc_datku >= 10000)
             {
                cout << baza_darczyncow[i].nazwisko << ": ";
                cout << baza_darczyncow[i].wysokosc_datku<<endl;
                ilosc_osob++;
             }
         }

        if(ilosc_osob == 0)
            cout << "Brak\n\n";

        cout << "Nasi Sponsorzy: \n";
        ilosc_osob = 0;

        for (int i = 0; i < ilosc_darczyncow; i++)
        {
             if(baza_darczyncow[i].wysokosc_datku < 10000 && baza_darczyncow[i].wysokosc_datku !=0)
             {
                cout << baza_darczyncow[i].nazwisko << ": ";
                cout << baza_darczyncow[i].wysokosc_datku<<endl;
                ilosc_osob++;
             }
        }
        if(ilosc_osob == 0)
            cout << "Brak\n\n";

    }
    delete [] baza_darczyncow;
    odczyt.close();
    cout << endl;

    return 0;
}

 

1 odpowiedź

+1 głos
odpowiedź 24 maja 2018 przez niezalogowany
wybrane 24 maja 2018 przez Junior_plusplus
 
Najlepsza

Zwykłe wczytywanie (>>) zostawia w buforze znak nowej linii - trzeba go odrzucić jeżeli korzysta się później z getline:

	int ilosc_darczyncow;
	odczyt >> ilosc_darczyncow;
	odczyt.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // dołącz w nagłówkach <limits>

	ofiarodawcy * baza_darczyncow = new ofiarodawcy[ilosc_darczyncow];

	for (int i = 0; i < ilosc_darczyncow; i++)
	{
		getline(odczyt, baza_darczyncow[i].nazwisko);
		odczyt >> baza_darczyncow[i].wysokosc_datku;
		odczyt.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	}

lub tak:

	int ilosc_darczyncow;
	odczyt >> ilosc_darczyncow >> std::ws; // ws - white skip

	ofiarodawcy * baza_darczyncow = new ofiarodawcy[ilosc_darczyncow];

	for (int i = 0; i < ilosc_darczyncow; i++)
	{
		getline(odczyt, baza_darczyncow[i].nazwisko);
		odczyt >> baza_darczyncow[i].wysokosc_datku >> std::ws;
	}
komentarz 24 maja 2018 przez Junior_plusplus Obywatel (1,130 p.)

I gitara !!!

Wszystko pięknie działa po zastosowaniu ">>ws;".

Bardzo, bardzo dziękuję za pomoc i pozdrawiam !

Oto aktualny kod:

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <sstream>

using namespace std;

struct ofiarodawcy
{
    string nazwisko;
    double wysokosc_datku;
};

int main()
{
    char nazwa_pliku[30];
    ifstream odczyt;

    cout << "Witaj! Prosze podaj nazwe pliku ktory chcesz wczytac: ";
    cin.getline(nazwa_pliku, 30);
    cout << endl;
    odczyt.open(nazwa_pliku);

    if (!odczyt.is_open())
     {
        cout << "Otwarcie pliku " << nazwa_pliku << " nie powiodlo sie.\n";
        cout << "Program zostanie zakonczony.\n";
        exit (EXIT_FAILURE);
    }
    string ilosc_darczyncow_konwersja;
    getline(odczyt,ilosc_darczyncow_konwersja);

    int ilosc_darczyncow;
    istringstream is(ilosc_darczyncow_konwersja);
    is>>ilosc_darczyncow>>ws;

    ofiarodawcy * baza_darczyncow = new ofiarodawcy[ilosc_darczyncow];

    for (int i = 0; i < ilosc_darczyncow; i++)
    {
        getline(odczyt, baza_darczyncow[i].nazwisko);
        odczyt>>baza_darczyncow[i].wysokosc_datku>>ws;
    }
     if (odczyt.eof())
        cout << "\n\nKoniec pliku.\n";
    else if (odczyt.fail())
        cout << "Wczytywanie danych przerwane - blad.\n";
    else
        cout << "Wczytywanie danych przerwane, przyczyna nieznana.\n";
    if (ilosc_darczyncow == 0)
        cout << "Nie przetworzono zadnych danych.\n";
    else
    {
        int ilosc_osob = 0;

        cout << "\nNasi Wspaniali Sponsorzy: \n";
        for (int i = 0; i < ilosc_darczyncow; i++)
        {
             if(baza_darczyncow[i].wysokosc_datku >= 10000)
             {
                cout << baza_darczyncow[i].nazwisko << ": ";
                cout << baza_darczyncow[i].wysokosc_datku<<endl;
                ilosc_osob++;
             }
         }

        if(ilosc_osob == 0)
            cout << "Brak\n\n";

        cout << "\nNasi Sponsorzy: \n";
        ilosc_osob = 0;

        for (int i = 0; i < ilosc_darczyncow; i++)
        {
             if(baza_darczyncow[i].wysokosc_datku < 10000 && baza_darczyncow[i].wysokosc_datku !=0)
             {
                cout << baza_darczyncow[i].nazwisko << ": ";
                cout << baza_darczyncow[i].wysokosc_datku<<endl;
                ilosc_osob++;
             }
        }
        if(ilosc_osob == 0)
            cout << "Brak\n\n";

    }
    odczyt.close();
    delete [] baza_darczyncow;

    cout << endl;

    return 0;
}

 

Podobne pytania

0 głosów
2 odpowiedzi 498 wizyt
pytanie zadane 2 września 2018 w C i C++ przez vog Początkujący (370 p.)
0 głosów
2 odpowiedzi 641 wizyt

92,455 zapytań

141,263 odpowiedzi

319,099 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...