Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.net  
   

Die mobilen Seiten von c++.net:
https://m.c-plusplus.net

  
C++ Forum :: C++ (alle ISO-Standards) ::  .txt in struct mit array member einlesen  
Gehen Sie zu Seite 1, 2  Weiter
  Zeige alle Beiträge auf einer Seite
Auf Beitrag antworten
Autor Nachricht
Atrom
Unregistrierter




Beitrag Atrom Unregistrierter 13:21:39 28.12.2016   Titel:   .txt in struct mit array member einlesen            Zitieren

Hallo!

Im Rahmen meines Studiums besuche ich eine Vorlesung in der wir Programmieren mit C++ lernen. Da dies mein erstes Semester ist, bin ich also noch ein blutiger Anfänger. Ich hänge nun an einer Hausaufgabe fest, in der es darum geht, per fstream Daten aus einer .txt in eine struct einzulesen.

Zum besseren Verständnis, kopier ich euch mal die Aufgabenstellung, damit ich mein Problem besser beschreiben kann:

Zitat:
Eine Sorte besteht aus maximal 5 Zutaten. Daraus ergibt sich folgende Struktur:

struct schokolade
{
char name[20];
int gewicht;
int zutat_id[5];
int menge_in_prozent[5];
};

Sind weniger als 5 Zutaten für eine bestimmte Sorte nötig, wird die ID der ersten, nicht belegten Zutat mit der Zahl -1 versehen. Zur Herstellung aller Schokoladensorten existieren sieben Zutaten.

Lesen Sie die Zusammensetzung der Schokoladensorten aus der Datei schoki.txt ein. Die Datei ist nach folgendem Schema aufgebaut:

zartbitter ← Name der Schokoladensorte
100 ← Gewicht der Schokolade in Gramm
2 ← Anzahl der Zutaten
kakao 70 ← Name der Zutat und Anteil der Zutat am Gesamtgewicht in %
zucker 30 ← Name der Zutat und Anteil der Zutat am Gesamtgewicht in %

Beachten Sie, dass der Name der Zutat in eine ID umgewandelt werden muss und dass in der Datei schoki.txt genau drei Sorten Schokolade beschrieben sind..

Die Zutaten zur Schokoladenherstellung besitzen folgende Daten:
einen Namen und
einen Preis pro 100 Gramm in Euro.
Daraus ergibt sich folgende Struktur:

struct zutat
{
char name[20];
float preis_pro_100gramm;
};

Aus der Datei zutaten.txt lesen Sie alle zur Verfügung stehenden Zutaten und deren jeweiligen Preis ein. Die Reihenfolge der Zutaten in der Datei bestimmt die Identifikationsnummer (ID) einer Zutat: Die erste Zutat aus der Datei bekommt die ID 0, die Zweite eine 1 und so fort. Die ID kann also mit dem Feldindex einer Zutat in der Auflistung gleichgesetzt werden.


Die .txt Dateien sehen so aus.

schoki.txt:

vollmilch_mandel
100
5
kakao 34
kakaobutter 10
milchpulver 20
zucker 28
mandeln 8

marzipan
100
3
kakao 50
zucker 25
marzipan 25

keksschoki
100
5
kakao 40
mandeln 7
kakaobutter 8
zucker 30
keks 15

zutaten.txt:

mandeln 1.10
marzipan 1.22
milchpulver 0.6
kakao 0.82
kakaobutter 2.2
keks 0.64
zucker 0.14

Das Einlesen der zutaten.txt läuft reibungslos. Jedoch habe ich Probleme mit dem Einlesen der anderen Datei. Vor allem, da in dem ersten struct zwei int arrays sind. Mein problem hier ist, dass ich die Namen der Zutaten in eine ID umwandeln soll, also 7 Zutaten von oben nach unten mit 0-6. Vllt könnt ihr mir helfen, wie ich es hinbekomme, dass es mir die schoki.txt ordentlich einliest und ich statt der Namen der Zutaten, welche für die jeweilige Sorte benötigt werden, eine ID einliest.

Hier ist mein Stück Code, welches ich bisher habe.

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
 
struct schokolade               //struct für Schokolade
{
    string name;
    int gewicht;
    int zutat_id[5];
    int menge_in_prozent[5];
};
 
struct zutat                    //struct für die Zutaten
{
    string name;
    float preis_pro_gramm;
};
 
int main()
{
    zutat feld[7];              //einlesen der Datei "zutaten.txt" mit 7 Einträgen
    int i = 0;
    ifstream file;
    file.open("zutaten.txt");
    if(file.is_open()){
 
        for(i; i<7; i++)
        {
 
            file >> feld[i].name;
            file >> feld[i].preis_pro_gramm;
        }
 
        file.close();
    }
    else{
        cout << "Datei Konnte nicht geöffnet werden!" << endl;
        return 0;
    }
 
    schokolade feld_2[3];
    int j=0;
    int k=0;
    for(j; j<3; j++)
    {
        for(int i=0; i<5; i++)
        {
 
        feld_2[j].zutat_id[i] = i;      //Vergeben einer ID für die jeweilige Zutat
        }
    }
 
 
    ifstream file_2;                    //Einlesen der Datei "schoki.txt" mit 3 Einträgen
    file.open("schoki.txt");
    if(file.is_open()){
 
        file_2 >> feld_2[j].name;
        file_2 >> feld_2[j].gewicht;
        file_2 >> feld_2[j].menge_in_prozent[5];
    }
    file_2.close();
 
    for(int i=0; i<7; i++)  //ab hier nur zur Veranschaulichung, ob es die Daten ordentlich einliest
    {
        cout << "Name: " << feld[i].name <<" Preis pro Gramm: " << feld[i].preis_pro_gramm << "\n";
    }
    for(int j=0; j<3; j++)
    {
        for (int i=0; i<7; i++)
        {
            cout << "Name: " << feld_2[j].name <<" Gewicht: " << feld_2[j].gewicht << "ID: " << feld_2[j].zutat_id[i] <<" Menge in Prozent: " << feld_2[j].menge_in_prozent << "\n";
        }
    }
    return 0;
}


Sry für die Wall of Text, aber ich weiß leider nicht wie ich das Problem besser beschreiben soll :( :( :(
HarteWare
Mitglied

Benutzerprofil
Anmeldungsdatum: 16.02.2013
Beiträge: 431
Beitrag HarteWare Mitglied 16:32:05 28.12.2016   Titel:              Zitieren

wie wäre es, wenn du die Zutaten in ein string array packst und als ID die indices nimmst? Bei sehr vielen Zutaten würde sich wohl auch eine map eignen (Zutat = Key, ID = Value).
Jockelx
Mitglied

Benutzerprofil
Anmeldungsdatum: 19.12.2009
Beiträge: 1257
Beitrag Jockelx Mitglied 16:34:53 28.12.2016   Titel:   Re: .txt in struct mit array member einlesen            Zitieren

Atrom schrieb:
Vllt könnt ihr mir helfen, wie ich es hinbekomme, dass es mir die schoki.txt ordentlich einliest und ich statt der Namen der Zutaten, welche für die jeweilige Sorte benötigt werden, eine ID einliest.


Hallo,

das kannst du sicherlich auch selber:

C++:
size_t nameToIndex(const std::string& name)  // ggf. array mit übergeben
{
...
}
...
size_t index = nameToIndex(readName);


ps: Code-Vorgabe sieht schrottig aus. Nach dem Kurs unbedingt ein gutes Buch lesen, damit sich der Mist nicht verfestigt.
Atrom
Unregistrierter




Beitrag Atrom Unregistrierter 16:41:47 28.12.2016   Titel:              Zitieren

Danke erstmal für den Tipp. Ja, dass das schrottig aussieht, mag sein...aber anders wird es uns auch nicht gezeigt.
dref
Unregistrierter




Beitrag dref Unregistrierter 17:04:32 28.12.2016   Titel:              Zitieren

Zum Problem selber: Variablen sollten immer so lokal wie möglich sein, das zeigt sich in deinem bei j und file/file_2. Wenn du keine Funktionen verwenden möchtest, kannst du auch Scopes einfügen.
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
for(j; j<3; j++) // so lokal wie möglich, also int j=0;.., schlecht: nackte Zahlen wie auch 5&7, etwas besser wäre es, Konstanten zu verwenden
    {
        for(int i=0; i<5; i++) // richtig, hier undurchsichtig, da dieses i Darüberleigendes überdeckt
        {
 
        feld_2[j].zutat_id[i] = i;      //Vergeben einer ID für die jeweilige Zutat
        }
    }
 
//  ifstream file_2("schoki.txt") <- besser direkt so
    ifstream file_2;                    //Einlesen der Datei "schoki.txt" mit 3 Einträgen
 
    file.open("schoki.txt"); // schlecht: sollte wohl file_2 sein
    if(file.is_open()){ //
 
        file_2 >> feld_2[j].name; // s.o., hier das resultierende Problem mit dem stream und auch j, j ist hier 3, der Code sollte wohl in einer Schleife stehen
        file_2 >> feld_2[j].gewicht;
        file_2 >> feld_2[j].menge_in_prozent[5];
    }

Das ist nur, was mir direkt ins Auge gesprungen ist.
Jockelx
Mitglied

Benutzerprofil
Anmeldungsdatum: 19.12.2009
Beiträge: 1257
Beitrag Jockelx Mitglied 17:06:15 28.12.2016   Titel:              Zitieren

Atrom schrieb:
Danke erstmal für den Tipp. Ja, dass das schrottig aussieht, mag sein...aber anders wird es uns auch nicht gezeigt.

Ich weiss, deshalb ja auch 'Code-Vorlage' (gemeint war die der Aufgabe).
Atrom
Unregistrierter




Beitrag Atrom Unregistrierter 17:15:41 28.12.2016   Titel:              Zitieren

dref schrieb:
Zum Problem selber: Variablen sollten immer so lokal wie möglich sein, das zeigt sich in deinem bei j und file/file_2. Wenn du keine Funktionen verwenden möchtest, kannst du auch Scopes einfügen.
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
for(j; j<3; j++) // so lokal wie möglich, also int j=0;.., schlecht: nackte Zahlen wie auch 5&7, etwas besser wäre es, Konstanten zu verwenden
    {
        for(int i=0; i<5; i++) // richtig, hier undurchsichtig, da dieses i Darüberleigendes überdeckt
        {
 
        feld_2[j].zutat_id[i] = i;      //Vergeben einer ID für die jeweilige Zutat
        }
    }
 
//  ifstream file_2("schoki.txt") <- besser direkt so
    ifstream file_2;                    //Einlesen der Datei "schoki.txt" mit 3 Einträgen
 
    file.open("schoki.txt"); // schlecht: sollte wohl file_2 sein
    if(file.is_open()){ //
 
        file_2 >> feld_2[j].name; // s.o., hier das resultierende Problem mit dem stream und auch j, j ist hier 3, der Code sollte wohl in einer Schleife stehen
        file_2 >> feld_2[j].gewicht;
        file_2 >> feld_2[j].menge_in_prozent[5];
    }

Das ist nur, was mir direkt ins Auge gesprungen ist.


Danke! Habe ich gleich mal ausgebessert!


Das Problem ist halt, dass das mit dem fstream nur mal 10min angeschnitten wurde , an einem sehr simplen Beispiel und dieses "nametoindex" war mir gar nicht bekannt.
Jockelx
Mitglied

Benutzerprofil
Anmeldungsdatum: 19.12.2009
Beiträge: 1257
Beitrag Jockelx Mitglied 17:30:25 28.12.2016   Titel:              Zitieren

Atrom schrieb:
und dieses "nametoindex" war mir gar nicht bekannt.

Das gibt es ja auch nicht. Das solltest du selber machen.
Hab nur die Signatur als Denkansatz geliefert - der Rest schreibt sich ja dann fast alleine.
temi(temp)
Unregistrierter




Beitrag temi(temp) Unregistrierter 23:17:01 28.12.2016   Titel:              Zitieren

Du hast die Zutaten doch bereits in ein Array eingelesen. Der Index dieses Array entspricht genau der gesuchten ID.

Jetzt brauchst du beim Einlesen der Schokolade nur jeweils in einer Schleife das Zutatenarray von Anfang an durchzugehen bis der name der Zutat dem Namen in "feld.name" entspricht (blöder Name übrigens, besser wäre z.B. zutatenliste). Den entsprechenden Index nimmst du dann als Id für die Schokolade.
Atrom
Unregistrierter




Beitrag Atrom Unregistrierter 01:38:50 30.12.2016   Titel:              Zitieren

Also danke für eure Hilfe Leute, ich habe es jetzt hinbekommen! :) :live:
C++ Forum :: C++ (alle ISO-Standards) ::  .txt in struct mit array member einlesen  
Gehen Sie zu Seite 1, 2  Weiter
Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.net ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.