Dateien einlesen.



  • Ich habe aus http://www.c-plusplus.net/forum/viewtopic-var-p-is-1009718.html#1009718 das Beispiel genutzt um Dateien in vectoren einzulesen.

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    int main() {
      ifstream ifs("datei.txt");
    
      if (!ifs)
        return 1;
    
      vector<unsigned char> vec;
      char chr;
    
      while (ifs.good()) {  
        ifs.get(chr);
        vec.push_back(chr);
      }
            ShowMessage("size:"+IntToStr(vec.size()));
            ShowMessage("capacity:"+IntToStr(vec.capacity()));
    
      ifs.close();
      return 0;
    }
    

    Die Datei ist jetzt Original 209 KB (214.200 Bytes) (nicht Speicher auf HDD!!)
    size() sagt: 154299
    capacity() sagt: 262144

    *nix peil*

    1. Warum sind die Werte unterschiedlich
    2. Warum stimmen die Werte nicht mit den zu lesenden Bytes überein.

    Eigentlich wollte ich statt

    handle=_open("datei.txt",_O_RDONLY);
    if (!handle) return;
    unsigned char array = (unsigned char*) malloc(filesize+1);
    _read(handle,&array[0],filesize);
    _close(handle);
    

    das mit vectoren lösen, aber da passiert ja nur Quatsch 🙄 😕

    Etwas grundlegendes vergessen?



  • Hi!

    capacity Returns the largest possible size of the vector.

    Warum willst du überhaupt einen Vector nehmen? Ich halt das für Unsinn... :-S

    grüße



  • David_pb schrieb:

    capacity Returns the largest possible size of the vector.

    Das war wohl die Antwort auf die Frage: Was macht max_size(), oder?
    size() liefert die Anzahl der gespeicherten Elemente,
    capacity() die Anzahl von Elementen, die ohne Größenänderung des Vectors (also Speicherallokierung) gespeichert werden können. Drum ist size immer <= capacity.

    Ich weiss nicht was du mit den eingelesenen Daten sonst noch so vorhast, aber im zweiten Punkt muss ich David_pb recht geben ...

    grüße


  • Mod

    vector vergrössert den speicherblock nicht jeweils nur um ein element. warum das so ist, wurde gerade erst diskutiert:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-138510.html

    vector muss keine schlechte wahl für diesen zweck sein, tatsächlich ist es sogar eine sehr gute wahl, allerdings nicht mit der obigen methode :p
    wenn du mit der C methode filesize bereits kennst, diese information im C++ dem vector aber vorenthälst, musst du dich über merkwürdigkeiten nicht wundern 😉



  • Hi!

    @Sepp Brannigan:
    Danke für den Hinweis, du hast natürlich recht. Ich bin da wohl in der Zeile verrutscht! 😉

    grüße



  • Und was den Unterschied zwischen Dateigröße und Vektorgröße angeht - Such mal im Forum nach Textfile vs. Binärfile 😉
    (im Klartext: Zeilenwechsel im File speichert Windows als \r\n = 2 Byte, C wandelt die um in \n = 1 Byte)



  • Alternativ wollte ich das new verwendet, aber auch da habe ich leider meine Probleme mit.

    C Version

    unsigned char *variable = (unsigned char*) malloc(filesize+1);
    read(handle,&variable[0],filesize);
    free (variable);
    

    C++ mit new

    unsigned char *variable = new unsigned char(filesize+1);
    read(handle,&variable[0],filesize);
    delete[] variable;
    

    Ergebnis: Crash in read() 🙄

    C++ mit auto_ptr

    auto_ptr<unsigned char> variable( new unsigned char(filesize) );
    read(handle,&variable[0],filesize);
    

    Ergebnis: Binaerer Operator '[' : 'class std::auto_ptr<unsigned char>' definiert diesen Operator oder eine Konvertierung in einen für den vordefinierten Operator geeigneten Typ nicht

    Ich wüsste jetzt natürlich gerne warum new und auto_ptr nicht funktionieren 🤡



  • cianner schrieb:

    C++ mit new

    unsigned char *variable = new unsigned char(filesize+1);
    read(handle,&variable[0],filesize);
    delete[] variable;
    

    Ergebnis: Crash in read() 🙄

    ...

    Ich wüsste jetzt natürlich gerne warum new und auto_ptr nicht funktionieren 🤡

    Deine new-Version erzeugt EIN char mit dem Wert '(filesize+1)%256', um ein Array von chars anzulegen, benötigst du eckige Klammern:

    unsigned char* variable = new unsigned char[filesize+1];
    

    (und auto_ptr ist sowieso nur für Solo-Objekte vorgesehen - schau dir doch mal Boost's scoped_array an)



  • Danke! Nachdem ich den Text abgesendet hatte, ist mir das auch aufgefallen, ich wollte aber nicht direkt auf den Beitrag gleich antworten.

    Ich habe mir mal boost_1_33_1 raufgehauen.

    #include "boost/scoped_ptr.hpp" 
    using namespace boost;
    
    scoped_ptr<unsigned char> variable(new unsigned char[filesize+1]); 
    read(handle,&variable[0],filesize);
    

    Ergebnis: Binaerer Operator '[' : 'class boost::scoped_ptr<unsigned char>' definiert diesen Operator oder eine Konvertierung in einen für den vordefinierten Operator geeigneten Typ nicht 😞



  • scoped_ptr ist ja ebenfalls für Solo-Objekte gedacht - ich sagte vorhin scoped_array (und der hat auch einen Subscript-Operator).



  • Vielen Dank!! Scheisse wenn man nicht lesen kann 😉
    Jetzt muss ich doch gleich ne Zusatzfrage stellen. 🙄

    Ich will die variable in einer Klasse definieren.
    Als new würde man das so machen

    class bla
    {
    private:
    unsigned char *variable;
    }
    
    bla:bla()
    {
    long filesize = ......
    variable = new unsigned char[filesize+1];
    }
    

    Wie müsste das bei scoped_array() ausschauen? Ich bekomme es absolut nicht hin zu teilen *zu blöd dafür bin*



  • In dem Fall mußt du wohl die Initialisierungsliste des Ctors verwenden:

    class test
    {
    public:
      test(int fsize) : filsize(fsize), filedata(new unsigned char[fsize+1]
      {
        ...
      }
    private:
      int filesize;
      scoped_array<unsigned char> filedata;
      //bei näherem Überlegen: hier wäre ein shared_array wohl hilfreicher
    };
    


  • Das sind um die 30 Variablen die ich benötige, die müssen alle so initialisiert werden? *igh*



  • Argh ich wollte doch "Vorschau" anklickern.

    Anders gefragt... dieser Zweizeiler:

    unsigned char *variable;
    variable = new unsigned char[filesize+1];
    

    müsste bitte wie für scoped_array aussschauen?

    scoped_array<unsigned char> variable;
    variable(new unsigned char[filesize+1]);
    

    Hier meckert er ja das es keine Funktion ist. 🙄
    Und warum sollte shared_array besser geeignet sein?



  • 30 Variablen? Was soll denn das werden 😮 ?



  • scoped_array's besitzen keinen Zuweisungsoperator (und erst recht keinen op()), also mußt du sie direkt beim Erzeugen initialisieren:

    scoped_array<char> var(new char[size+1];
    

    (und shared_arrays haben den Vorteil, daß sie Referenzzählung und Kopier-Operationen unterstützen)

    PS: Im Magazin gibt es übrigens einen Artikel über die ganzen Boost-Smartpointer - den solltest du dir mal durchlesen 😉



  • Schade, dann nehme ich lieber die new/delete methode oder bleibe gleich beim Original. Das macht dann auch keinen wirklichen Unterschied.


Anmelden zum Antworten