Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

CeDoMain

Alter Hase

Beiträge: 587

Wohnort: Ilmenau

Beruf: Student für Mechatronik

  • Private Nachricht senden

11

26.01.2016, 17:32

Und so wird es noch einfacher:

Quellcode

1
2
3
Normal 0 0 193 53
Button_Hover 0 53 193 53
Button_Click 0 106 193 53

C-/C++-Quelltext

1
2
while (stream >> name >> x >> y >> width >> height);
// ...

;)
Wow! Das ist ja geil - das merke ich mir! So mache ich das jetzt immer. :D

Ich möchte noch darauf hinweisen, dass std::string hier schon nützliche Funktionen anbietet wie z.B. find oder substr. Auch ist std::string::npos recht nützlich in diesem Zusammenhang.
Ja klar, diese Methoden kenne ich - so mache ich das auch, aber vielleicht interessierts den TE was das Prinzip im Hintergrund ist: Trenner suchen und alles was dazwischen ist rauspicken, konvertieren und speichern. ;)
Mit freundlichem Gruß
CeDo
Discord: #6996 | Skype: cedomain

Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

12

26.01.2016, 18:42

Trenner suchen und alles was dazwischen ist rauspicken, konvertieren und speichern.
Für diese generelle Erklärung des Prinzips hättest Du nicht mal mit Code vorsagen müssen und er hätte sich selbst Gedanken machen können :)
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

cojo2015

Alter Hase

  • »cojo2015« ist der Autor dieses Themas

Beiträge: 516

Wohnort: bei mir zu Hause

Beruf: Schüler

  • Private Nachricht senden

13

29.01.2016, 19:16

Kurze Zwischenfrage: Immer, wenn eine neue Zeile begonnen hat (also z.B. "Buttons:"), dann muss ich doch eine neue Instanz von der Struktur erstellen, oder?

PS: Hier ist der Code

Header

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef CONFIG_H
#define CONFIG_H

#include <string>
#include <fstream>

class Config
{
public:
    Config();

    void read(std::string filename);

private:
    struct Data
    {
        std::string name;
        int x, y, width, height;
    };
    std::ifstream _stream;
};

#endif // !CONFIG_H


Source

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "Config.h"

Config::Config()
{
}

void Config::read(std::string filename)
{
    Data data;

    _stream.open(filename);
    while (_stream >> data.name >> data.x >> data.y >> data.width >> data.height);
    _stream.close();
}


Ist das bis hierhin soweit richtg?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

14

29.01.2016, 22:23

Kurze Zwischenfrage: Immer, wenn eine neue Zeile begonnen hat (also z.B. "Buttons:"), dann muss ich doch eine neue Instanz von der Struktur erstellen, oder?

Würde man mal meinen!?

cojo2015

Alter Hase

  • »cojo2015« ist der Autor dieses Themas

Beiträge: 516

Wohnort: bei mir zu Hause

Beruf: Schüler

  • Private Nachricht senden

15

30.01.2016, 10:22

Die Titel würde ich weglassen, weil der steht ja in jeder Zeile nochmal vor dem Unterstrich. Lasst die Datei lieber so aussehen:

Und so wird es noch einfacher:


Ich hab eure beiden Varianten "kombiniert" und so sieht es jetzt aus (Anhang).
Der Code sieht nun so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void Config::read(std::string filename)
{
    _stream.open(filename);
    std::string Token = "";

    //create a intance for each object
    Data Button_Normal, Button_Hover, Button_Click;
    Data Combobox_Normal, Combobox_Hover, Combobox_Click;
    Data Tab_Normal;
    Data Progessbar_Front, Progessbar_Back;
    Data Radiobutton_False, Radiobutton_True;
    Data Slider_Thump, Slider_Track;
    Data Checkbox_Unchecked, Checkbox_checked;
    Data Textbox_Normal;

    //go through each line
}


Aber leider habe ich keine Ahnung, wie ich JEDE Zeile einzeln auslesen soll bzw. in die nächste Zeile "springen" soll :dash:
PS: Ich habe bis jetzt immer nur einen Wert aus einer Datei "herausgelesen", also ich habe so etwas noch nie gemacht...
»cojo2015« hat folgende Datei angehängt:
  • config.txt (477 Byte - 39 mal heruntergeladen - zuletzt: 01.04.2024, 07:51)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

16

30.01.2016, 10:47

Wie wär's mit sowas wie:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
std::vector<Data> readConfig(const char* filename)
{
    std::ifstream stream(filename);

    if (!stream)
        throw std::runtime_error("unable to open config file");

    std::vector<Data> data;

    std::string name;
    int x, y, width, height;
    while (stream >> name >> x >> y >> width >> height)
        data.emplace_back(name, x, y, width, height);

    if (stream.fail())
        throw std::runtime_error("error reading config file");

    return data;
}

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »dot« (30.01.2016, 10:53)


cojo2015

Alter Hase

  • »cojo2015« ist der Autor dieses Themas

Beiträge: 516

Wohnort: bei mir zu Hause

Beruf: Schüler

  • Private Nachricht senden

17

30.01.2016, 11:03

Wie wär's mit sowas wie:

Oh danke :D Ich habe es so implementiert:

C-/C++-Quelltext

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
#ifndef CONFIG_H
#define CONFIG_H

#include <string>
#include <fstream>
#include <vector>

class Config
{
private:
    struct Data
    {
        std::string name;
        int x, y, width, height;
    };

public:
    Config() {  };

    std::vector<Data> readConfig(const char* filename)
    {
        std::ifstream stream(filename);
        if (!stream)
            throw std::runtime_error("unable to open config file");

        std::vector<Data> data;
        std::string name;
        int x, y, width, height;

        while (stream >> name >> x >> y >> width >> height)
            data.emplace_back(name, x, y, width, height);

        if (stream.fail())
            throw std::runtime_error("error reading config file");

        return data;
    }
};

#endif // !CONFIG_H


Ich habe zuerst den private-Bereich gemacht, weil ich sonst keinen Zugriff auf Data habe...
Aber nun habe ich (wie sonst auch immer) einen Fehler: C2661 "Config::Data::Data": Keine überladene Funktion akzeptiert 5 Argumente. Bin ich wieder zu blöd ?(

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

18

30.01.2016, 11:10

Wieso brauchst du denn hier eine Klasse und wieso das in eine Methode packen? Wenn Data private ist, kann niemand was mit dem Rückgabewert der Methode anfangen!? Du brauchst noch ein #include <stdexcept>. Der Grund für deinen Compilerfehler ist, dass Data keinen passenden Konstruktor hat. Entweder Data einen passenden Konstruktor geben oder z.B. so machen: data.emplace_back({ name, x, y, width, height });.

Btw: Besser würde man die Implementierung dieser Funktion in eine .cpp Datei packen, das #include <fstream> und #include <stdexcept> braucht man dann auch nur in der .cpp Datei.

Werbeanzeige