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

Wczytywanie danych z pliku do tablicy struktur.

VPS Starter Arubacloud
0 głosów
1,265 wizyt
pytanie zadane 11 stycznia 2019 w C i C++ przez kamyk2 Początkujący (420 p.)

Witam, mam zadanie, w którym muszę napisać program składający się z paru funkcji. Pierwszą z nich jest funkcja przyjmująca jako argumenty referencję do strumienia wejściowego (istream) oraz referencję do struktury o nazwie Item.

Wygląda ona tak:

struct Item
{
	char name[32];
	int volume;
	double value;
};

W int main() zadeklarowałem:

ifstream inFile("input.txt");

Zatem funkcja wygląda u mnie tak:

bool loadItem(istream &inFile, Item &item)
{
    if (!inFile) {
        cout << "file error";
        return false;
    } for(int i = 0; i < 5(przykładowo 5, nie doszedłem jak zaimplementować to dla n); i++)
    {
        inFile.getline(item.name, 32);
        inFile >> item.volume >> item.volume;
    } return true;
}

Funkcja ma zwracać prawdę jeżeli uda się wczytać ze strumienia nazwę, objętość oraz wartość przedmiotów, gdy plik np. skończy się lub zostanie napotkany błąd ma być zwrócony false. 

I tutaj zaczyna się problem. Jak  wczytać do tablicy dynamicznej struktur, (którą utworzyłem w mainie w podany niżej sposób) wszystkie przedmioty odczytane z pliku, kiedy funkcja loadItem przyjmuje tylko referencję do przedmiotu oraz tą referencję do istream.

Item * itemsList = new Item [n];

Natomiast lista w pliku .txt wygląda na przykład tak:


grzesiek 300 2.5
twix 340 1.30
3bit 150 2.85


 

1 odpowiedź

+1 głos
odpowiedź 11 stycznia 2019 przez mokrowski Mędrzec (155,460 p.)
wybrane 11 stycznia 2019 przez kamyk2
 
Najlepsza

Zdecyduj czy chcesz mieć loadItem(...) czy loadItems(...). W tym drugim przypadku przekaż do loadItems(...) kontener std::vector<Item> przez co unikniesz jawnego zarządzania pamięcią poprzez new i delete.

komentarz 11 stycznia 2019 przez kamyk2 Początkujący (420 p.)
Czytam polecenie i jest w nim napisane:

"Funkcja powinna wczytywać z podanego strumienia nazwę, objętość i wartość przedmiotu."

Natomiast w poleceniu do zadania:

"Z pliku z danymi wczytuje do tablicy dynamicznej kolejne przedmioty tak długo, aż skończy się plik"

Nie rozumiem jak ma to być wykonywane.
komentarz 11 stycznia 2019 przez mokrowski Mędrzec (155,460 p.)
No cóż ... czyli jak widzę twórca pytania nakazał używanie new i delete bo tablicę dynamiczną alokujesz z użyciem new. Nie masz więc wyjścia.

Będziesz alokował tablicę na początku z jakąś wielkością elementów i w momencie wypełnienia jej (niezbędne zliczanie ilości Item'ów), alokujesz następną 2x większą a elementy z pierwotnej kopiujesz. Po skopiowaniu, pierwotną tablicę zwalniasz.

Smutne jest to że std::vector właśnie realizuje taki algorytm i robi to bezpiecznie a Tobie nakazano to zaimplementować.

W języku C++ jeśli używasz new, nie wolno użyć Ci realloc(...) bo formalnie generuje on w połączeniu z new, zachowanie niezdefiniowane.
komentarz 11 stycznia 2019 przez kamyk2 Początkujący (420 p.)
Dzięki za dotychczasową pomoc. A w takim razie po co mi w funkcji bool loadItem ta referencja do przedmiotu? skoro muszę i tak utworzyć tablicę dynamiczną Item * items = new Item[50] powiedzmy?
komentarz 11 stycznia 2019 przez mokrowski Mędrzec (155,460 p.)
No bo podasz tam jako argument Items[x] aby funkcja wpisała wartość.
komentarz 11 stycznia 2019 przez kamyk2 Początkujący (420 p.)
bool loadItem(istream &is, Item *&item)
{
	if (is.good() == true)
	{
		int i = 0;
		while (!is.eof())
		{
			is.getline(item[i].name, 32);
			is >> item[i].volume;
			is >> item[i].value;
			i++;
		} return true;
	}
	else { cout << "Nie mozna otworzyc pliku"; return false; }
}

Natomiast w int main()

Item * items = new Item[100];

Funkcja wyrzuca jakiś błąd, ale mam rozumieć że chodziło o taki mechanizm?

1
komentarz 11 stycznia 2019 przez mokrowski Mędrzec (155,460 p.)

Masz tu ideowo. Mam nadzieję że teraz jasne i będziesz w stanie to napisać :)

#include <iostream>
#include <fstream>

struct Item
{
    char name[32];
    int volume;
    double value;
};

bool loadItem(std::istream& inFile, Item &item)
{
    if(!inFile) {
        std::cerr << "file error";
        return false;
    }
    inFile.getline(item.name, 32);
    inFile >> item.volume >> item.value;
    return !inFile.fail();
}

void grow_table(....)
{
    // Funkcja powiększania tabeli...
}

int main() {
    std::ifstream inFile("input.txt");
    std::size_t index = 0;
    std::size_t capacity = 100;
    Item * itemsList = new Item[capacity];
    while(loadItem(inFile, itemsList[index]))
    {
        ++index;
        if(index == capacity) {
            grow_table(...);
        }
    }
}

 

Podobne pytania

0 głosów
0 odpowiedzi 759 wizyt
pytanie zadane 27 maja 2020 w C i C++ przez pozdro600 Początkujący (260 p.)
0 głosów
1 odpowiedź 213 wizyt
pytanie zadane 12 lipca 2015 w C i C++ przez hit02 Nałogowiec (33,970 p.)
0 głosów
1 odpowiedź 278 wizyt
pytanie zadane 1 października 2020 w C i C++ przez magda_19 Gaduła (3,080 p.)

92,453 zapytań

141,262 odpowiedzi

319,087 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!

...