kostenloser Webspace werbefrei: lima-city


Dateien einlesen

lima-cityForumProgrammiersprachenC/C++ und D

  1. Autor dieses Themas

    notinthetext

    Kostenloser Webspace von notinthetext, auf Homepage erstellen warten

    notinthetext hat kostenlosen Webspace.

    Mag jetzt in der Kombination ein wenig komisch rüber kommen, aber ich beschäftige mich erst seit kurzem mit C++. Und wie das so ist, habe ich gewaltige Ambitionen. Ich komme mal schnell zum Problem: Ich möchte 3D-Objekte und Texturen in Dateien schreiben und auslesen. ( Erstmal jeweils in eine Datei, später habe ich dann vor, das ganze zusammen in eine Datei zu packen. Wie auch immer... )
    Das Problem an der ganzen Sache ist: Ich habe keine Ahnung, wie man das macht.

    Meine Vorstellung ist in etwa so, dass ich erstmal einen Datei-Header habe, in dem steht, um welche Art von Datei es sich handelt, eventuell eine Kennzeichnung für das Objekt/die Textur und wie viele Daten sich darin befinden.Geeignete Strukturen habe ich dafür bereits, nun will ich die nur noch platzsparend ( Nicht komprimiert,.das wäre überzogen.. ) in eine Datei packen und halt wieder auslesen können.

    Nun habe ich mich ein wenig durchs Internet gelesen und ein paar Schnipsel gefunden. Leider wirft mir das auch nur Fehlermeldungen aus. Hier ein mal was ich habe.
    const unsigned long FM_OBJECTFILE_ID = 0xDEFF0001;
    const unsigned long FM_TEXTUREFILE_ID = 0xDEFF0002;
    
    struct filehead{
        unsigned long fTypeIdentifier;
        unsigned long fDataLength;
    };
    
    int filemanager::loadFile(std::string filepath)
    {
        filehead file_head;
        std::ifstream myfile (filepath.c_str(), ios::in|ios::binary);
        if(myfile.is_open())
        {
            myfile.read(file_head, sizeof(file_head));
            myfile.close();
            printf("File-Size:%i\n", file_head.fDataLength);
        }
    }
    
    int filemanager::saveFile(std::string filepath)
    {
        filehead file_head;
        file_head.fTypeIdentifier = FM_OBJECTFILE_ID;
        file_head.fDataLength = 1024;
        mFileData = new char[1024];
        for(int i = 0; i <=1023; i++)
        {
            mFileData[i] = 0xDE;
        }
    
        ofstream file (filepath.c_str(), ios::out|ios::binary);
        if(file.is_open())
        {
            file.write(filehead, sizeof(filehead));
            file.write(mFileData, 1024);
            file.close();
        }
    }
    Dabei bekomme ich die Fehlermeldung
    D:\Documents\Workspace\CPP\oGL\openGLEngine\filemanagement.cpp|16|error: no matching function for call to `std::basic_ifstream<char, std::char_traits<char> >::read(filehead&, unsigned int)'|
    Dazu habe ich ein wenig gegoogled, aber leider nichts brauchbares gefunden.

    Könnt ihr mir da helfen?
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Hallo notinthetext,

    Du musst der ifstream.read()-Methode einen Zeiger auf Deine filehead-Struktur übergeben und evtl. noch casten:
    myfile.read(static_cast<char *>(&file_head), sizeof(file_head));
    Beim Schreiben musst Du es analog machen:
    file.write(static_cast<char *>(&filehead), sizeof(filehead));



  4. Autor dieses Themas

    notinthetext

    Kostenloser Webspace von notinthetext, auf Homepage erstellen warten

    notinthetext hat kostenlosen Webspace.

    Alles klar, so funktioniert es.
    int filemanager::loadFile(std::string filepath)
    {
        filehead file_head;
        std::ifstream   in(filepath.c_str());
        in.read(reinterpret_cast<char*>(&file_head),sizeof(filehead));
        mFileData = new char[file_head.fDataLength];
        return 0;
    }
    
    int filemanager::saveFile(std::string filepath)
    {
        filehead file_head;
        file_head.fTypeIdentifier = FM_OBJECTFILE_ID;
        file_head.fDataLength = 1024;
        mFileData = new char[1024];
        for(int i = 0; i <=1023; i++)
        {
            mFileData[i] = 0xDE;
        }
        std::ofstream odatei;
        odatei.open(filepath.c_str(), std::ios::out|std::ios::binary|std::ios::trunc);
        odatei.write(reinterpret_cast<char*>(&file_head), sizeof(filehead));
        odatei.write(mFileData, 1024);
        return 0;
    }
    Ich habe zwar nicht ganz begriffen, weshalb das so ist, aber darum soll es erstmal nicht gehen.

    Vielen Dank dafür. :)
  5. Hallo notinthetext,

    vielleicht kann ich noch etwas Klarheit in die Sache bringen:
    Wenn Du in C++ eine Variable hast, dann gibt es drei Arten wie eine solchen an eine Funktion oder Methode übergeben werden kann:
    1. Als Wert
    2. Als Zeiger
    3. Als Referenz
    Hier ein kleines Beispiel zum Spielen:
    #include <iostream>
    
    using namespace std;
    
    struct point
    {
      double x;
      double y;
    }
    
    void pass_by_value(point p)
    {
      p.x += 3.0;
    }
    
    void pass_by_pointer(point * p)
    {
      p->x += 3.0;
    }
    
    void pass_by_reference(point &p)
    {
      p.x += 3.0;
    }
    
    void test()
    {
      point p;
    
      p.x = 0.0;
      p.y = 0.0;
    
      pass_by_value(p);
      cout << p.x << " " << p.y << endl; // 0.0 0.0
      
      pass_by_pointer(&p);
      cout << p.x << " " << p.y << endl; // 3.0 0.0
    
      pass_by_reference(p);
      cout << p.x << " " << p.y << endl; // 6.0 0.0
    }
    Wenn man Variablen als Wert übergibt, dann bekommt die Funktion bzw. Methode eine Kopie der Variable und Änderungen an dieser haben keine Auswirkung auf die ursprüngliche Variable.
    Wenn man einen Zeiger übergibt, d.h. die Adresse der ursprünglichen Variabel, dann kann die Funktion damit die ürsprüngliche Variable ändern.
    Wenn man die Variable als Referenz übergibt passiert eigentlich das selbe wie beim Zeiger es sieht nur anders aus. Eine nützliche Konvention ist, dass Zeiger immer dann verwendet werden, wenn die ursprüngliche Variable durch die Funktion geändert wird und ansonsten konstante Referenzen.
    Nun zurück zur write() und read()-Methode:
    Sowohl die zu schreibende als auch die zu lesende Datenmenge kann mitunter sehr groß sein und beim Lesen will man ja, dass die Daten am Ende in einer Variable stehen die außerhalb der Methode bekannt ist. Daher scheidet die Übergabe als Wert aus. Nachdem diese Methoden auch in der Lage sein sollen Variabeln von unterschiedlichen Typen zu lesen und zu schreiben wäre es mit Referenzen unter umständen etwas kompliziert geworden, weshalb man sich wohl auf den kleinsten gemeinsamen Nenner geeinigt hat: Die Adresse des Datenpuffers und die Anzahl der zu lesenden/schreibenden Bytes.
    Das funktioniert immer.

    Beitrag zuletzt geändert: 21.8.2012 2:35:37 von darkpandemic
  6. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!