Aus Datei in Array schreiben



  • Gedankenanstoß:

    char *fptr;
    // file pointer auf anfang der datei und um bspw. um 4 inkrementieren bei 
    // 4 byte integer
    // anzahl der zahlen entspr. size / 4
    
    while(!amEndeDerDatei)
    {
      int i = (int)*(fptr);
      fptr += 4;
    }
    


  • Ich würde die Elemente in einer Liste wie z.B. Vector speichern. Das hat den Vorteil, dass du einfach Elemente anhängen kannst und nicht bei der Erzeugung des Vector-Objekts wissen musst, wie viele Elemente du speichern wirst.

    Dann könntest du den Inhalt der Datei byteweise auslesen und in den Vector speichern.

    vector<int> Zahlen;
    
    while(true)
    {
        char tmp;
        inf1.get(tmp);
        if(inf1.eof())break;
        Zahlen.push_back(atoi(tmp));
    }
    
    // Die Anzahl der Zahlen kannst du mit Zahlen.size() ermitteln.
    // Zugriff auf einzelne Elemente ist mithilfe des []-operators möglich.
    


  • Ich würde auch vector<int> nehmen.

    Aber wenns denn unbedingt ein dynamisch erzeugtes Array sein soll, weiß zwar nicht warum, aber dann speicher doch alles in nem Vektor und schau mit .size() wie groß er ist, dann hast die anzahl und dann kannst ja vom vektor aus in eine dynamisches Array kopieren. Auch wenn das ganze unlogisch ist.

    Aber wie volkard schon sagt, nehm doch einfach nen vektor.

    Gruß freeG



  • Hallo,
    super, ich weiß jetzt wie ich es mache. Doch krabbels Denkanstoß habe ich nicht ganz verstanden. Kannst Du den noch etwas ausweiten, weil mich die Variante mit einem Pointer interessiert.

    Ich suche nämlich noch eine Methode, um die Anzahl der Zeichen zu bestimmen. Ihr bestimmt einfach die Größe des Vectors. Klar, das kann ich machen, doch kann ich irgendwas durch die Datei "laufen" lassen, bis das Dateiende erreicht worden ist?

    while(!inf1.eof())
    	{
    		//geh ein Zeichen weiter
    		len1++;
    	}
    

    Entspricht das krabbels Tipp? Ich weiß nur nicht, wie man "durch die Datei geht". Wie soll das mit einem Zeiger möglich sein oder muss ich get() benutzen?

    Vielen Dank
    lg, freakC++



  • freakC++ schrieb:

    Der Dateiinhalt könnte folglich so aussehen:

    125324564
    

    Nun möchte ich jede Ziffer in einem integer Array speichern. Dazu müsste ich wissen, wieviele Zifern in der Datei sind ...

    Musst Du nicht wissen. Man liest einfach Ziffer für Ziffer und steckt sie in einen Container. Und mit jeder Ziffer wird der Container um 1 größer.

    freakC++ schrieb:

    ... und wie ich Ziffer für Ziffer auslesen kann

    Das ist schon etwas schwieriger, da die Ziffer nun mal Ziffern und keine Zahlen sind. Ich tue zunächst mal so, als seinen es Zahlen. Dann geht es z.B. so:

    vector< int > ziffern;
    
        string inFile1 = "input.txt";
        ifstream inf1(inFile1.c_str());
        for( int ziffer; inf1 >> ziffer; )
            ziffern.push_back( ziffer );
        if( inf1.eof() )
        {
            cout << "Datei bis zum Ende gelesen; " << ziffern.size() << " Ziffern gelesen" << endl;
            // usw...
    

    Eine Zahl besteht aus einer Folge von Ziffern bis ein Zeichen auftaucht, welches keine Ziffer mehr ist oder EOF. Du willst aber die einzelnen Ziffern lesen. Dazu kann man sich ein Helferlein (hier read_ziffer) bauen, welches zunächst ein Zeichen liest und dieses in ein int wandelt. Also:

    struct read_ziffer
    {
        explicit read_ziffer( int& ziffer )
            : m_ziffer( ziffer )
        {}
        friend std::istream& operator>>( std::istream& in, const read_ziffer& rz )
        {
            char z;
            if( in >> z ) // einzelnes Zeichen lesen
            {
                if( z >= '0' && z <= '9' )
                    rz.m_ziffer = z - '0'; // Zeichen in Zahl umwandeln
                else
                    in.setstate( std::ios_base::failbit ); // .. das war keine Ziffer, also Fehler
            }
            return in;
        }
    private:
        read_ziffer& operator=( read_ziffer& ); // nur Compiler ruhigstellen
    
        int& m_ziffer;
    };
    

    und die Zeile 5 wird geändert nach

    for( int ziffer; inf1 >> read_ziffer( ziffer ); )
    

    Gruß
    Werner



  • freakC++ schrieb:

    Doch krabbels Denkanstoß habe ich nicht ganz verstanden. Kannst Du den noch etwas ausweiten, weil mich die Variante mit einem Pointer interessiert.

    So einen char* fptr, der in eine Datei zeigt, gibt es nicht. Auch belegt ein int nicht zwingend 4 Zeichen in der Datei (zumindest nicht in einer Textdatei, und davon reden wir hier doch). Jede Ziffer liegt in einer Textdatei als Zeichen vor.

    freakC++ schrieb:

    Ich suche nämlich noch eine Methode, um die Anzahl der Zeichen zu bestimmen.

    Du musst schon klarer sagen, was Du willst. Die Ziffern, die Anzahl der Ziffern oder die Anzahl der Zeichen?

    Anzahl der Zeichen geht so:

    int anzahlZeichen = distance( istream_iterator< char >( inf1 ), istream_iterator< char >() ); // erfodert #include <iterator>
    

    Gruß
    Werner



  • Hallo,
    vielen Dank! Ich werde mir den Lösungsvorschlag von Walter Salomon näher anschauen. Zuvor aber noch was ganz Banales:

    while(true)
    	{
    		char tmp; 
    		inf1.get(tmp); 
    		if(inf1.eof()) 
    			break;
    		Zahlen.push_back(tmp); 
    	}
    

    Ich möchte, dass die Abbruchbedinung im Schleifenkopf steht, da ich solche Endlosschleifenkonstrukte nicht sonderlich mag. Falls ich jedoch die if Bedinung einfach in den Schleifenkopf packe, so wird immer ein Zeichen, welches dann nicht vorhanden ist, zuviel ausgelesen. Wie muss ich den Schleifenkopf anpassen?

    Vielen Dank
    lg, freakC++



  • while(!inf1.eof())
    


  • freakC++ schrieb:

    Ich werde mir den Lösungsvorschlag von Walter Salomon näher anschauen.

    Nix für ungut, aber vielleicht ist es besser, Du liest Dir erst mal die Antworten genau durch bevor Du neue Fragen stellst....

    freakC++ schrieb:

    Zuvor aber noch was ganz Banales:

    while(true)
    	{
    		char tmp; 
    		inf1.get(tmp); 
    		if(inf1.eof()) 
    			break;
    		Zahlen.push_back(tmp); 
    	}
    

    Ich möchte, dass die Abbruchbedinung im Schleifenkopf steht, da ich solche Endlosschleifenkonstrukte nicht sonderlich mag. Falls ich jedoch die if Bedinung einfach in den Schleifenkopf packe, so wird immer ein Zeichen, welches dann nicht vorhanden ist, zuviel ausgelesen. Wie muss ich den Schleifenkopf anpassen?

    Dazu nimmst Du das Listing, welches ich Dir bereits gepostet habe

    Werner Salomon schrieb:

    vector< int > ziffern;
    
        string inFile1 = "input.txt";
        ifstream inf1(inFile1.c_str());
        for( int ziffer; inf1 >> ziffer; )
            ziffern.push_back( ziffer );
        if( inf1.eof() )
        {
            cout << "Datei bis zum Ende gelesen; " << ziffern.size() << " Ziffern gelesen" << endl;
            // usw...
    

    und ersetzt in den Zeilen 1 und 5 int durch char, und schon hast Du die gewünschte Schleife, mit Abbruch am Schleifenkopf.

    Und wieso eigentlich istream.get(char)? Du fragtest vorhin danach, wie man die Ziffern liest. Mit get() liest Du alle Zeichen inklusive 'Neue Zeile' usw.

    Gruß
    Werner



  • Ds war mein fehler, mit dem get().
    Und wenn du die Bedingung nicht im Schleifenkopf haben willst, kannst du das so machen: (Ist jetzt aber noch schlimmer als vorher, wie ich finde 😉 )

    bool runloop = true;
    while(runloop)
    {
        char tmp;
        inf1.get(tmp);
        if(inf1.eof()){runloop=false;continue;}
        if(tmp>='0'&&tmp<='9')Zahlen.push_back(atoi(tmp));
    }
    

    Der Vergleich in Zeile 7 müsste funtionieren, es werden halt die Ordnungsnummern verglichen. Und das atoi muss da auch hin, sonst wird nur die Ordnungsnummer der Zahl in das array geschrieben.

    MfG, Jochen



  • Wenn man es einfach ohne Operatorüberladung und mit schönen Schleifenbedingungen haben will, macht man es einfach so:

    std::ifstream file("test.txt"); 
    	vector<int> ziffern;
    	char tmp;
    	while(file.get(tmp))
    	{
    		if(isdigit(tmp))
    		{
    			ziffern.push_back(tmp-'0');
    		}
    	}
    

    Wenn einer noch ne Funktion kennt, die aus einem char einen int macht, wäre es noch schöner.


Anmelden zum Antworten