• 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.

0 głosów
128 wizyt
pytanie zadane 11 stycznia 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 przez mokrowski VIP (110,820 p.)
wybrane 11 stycznia 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 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 przez mokrowski VIP (110,820 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 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 przez mokrowski VIP (110,820 p.)
No bo podasz tam jako argument Items[x] aby funkcja wpisała wartość.
komentarz 11 stycznia 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 przez mokrowski VIP (110,820 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
1 odpowiedź 106 wizyt
pytanie zadane 12 lipca 2015 w C i C++ przez hit02 Nałogowiec (34,210 p.)
0 głosów
1 odpowiedź 219 wizyt
pytanie zadane 2 czerwca 2017 w C i C++ przez mibdbz Bywalec (2,060 p.)
Porady nie od parady
Zadając pytanie postaraj się o poprawną pisownię i czytelne formatowanie tekstu.Kompozycja

66,451 zapytań

113,207 odpowiedzi

239,680 komentarzy

46,704 pasjonatów

Przeglądających: 250
Pasjonatów: 13 Gości: 237

Motyw:

Akcja Pajacyk

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

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...