Nur jedes zweite Zeichen aus einem File...



  • Okay...
    hm...
    dann probiers doch mal mit streams

    ifstream in("Pfadname");   // Nicht vergessen \ als \\ zu schreiben
    char c[200];
    
    while ( !in.eof() )        // Schreibt alle Zeichen in der Datei in das Feld c
    {
        c[i] = in.get();
        i++;
    };
    c[i] = '\0';               // damit das Feld ab hier abgeschlossen wird
    

    Nach diesem Einlesen kannst du wie bereits oben angedeutet alles nochmal in eine andre variable schieben, bei der du nur jedes 2. zeichen berücksichtigst



  • Ok,vielen Dank!:)
    Ich dachte halt, es gäbe ein etwas elegantere Lösung, weil ich ja theoretisch im Vorfeld nicht wissen kann, wie groß das benötigte Feld ist.



  • Ich weiß nicht zwar nicht was Eleganz in C++ bedeutet,
    aber man könnte auch anstelle eines Feldes mit statischer Größe,
    ein zeiger auf eine char variable benutzen... damit kann man auch [] benutzen und so^^



  • noch besser wäre wohl ein vector<char>.



  • Eleganz in C++ bedeutet vermutlich Kapselung, generische Programmierung und raffinierter Einsatz der STL. 😉



  • Braunstein schrieb:

    noch besser wäre wohl ein vector<char>.

    und schneller wäre es,wenn man die 'länge' der datei misst und ein char-feld mit halber größe der länge dieser datei erstellt
    vector ist für sowas doch overkill,eleganz hin oder her



  • Um mal meine Vorredner aufzugreifen, man kann aus den beiden einzelnen Schritten, einlesen der Daten und anschließendes filtern, einen einzigen machen, das sähe dann zum Beispiel so aus:

    int main()
    {
        int laenge;
        ifstream datei;
        datei.open("Text.txt", ios:: binary);
    
    // Länge der Textdatei ermitteln
        datei.seekg (0, ios::end);
        laenge = datei.tellg();
        datei.seekg (0, ios::beg);
    
        char zeichen[laenge/2];
    
        for(int i=0;i<laenge;++i)
        {
            datei.get(zeichen[i]); //Einlesen eines Zeichens vom stream und speichern in zeichen
            datei.get();           //Einlesen eines weiteren Zeichens, aber wird nicht gespeichert
        }
    

    Mhhh wollte eigentlich mit seekg() ein Zeichen überspringen, das hat aber irgendwie nicht so geklappt wie ich es mir gedacht hatte.



  • Quellcode schrieb:

    char* tmp = .... // einlesenfunktion
    int size = sizeof(tmp) / sizeof(char); // ich glaub string hat eigenen size Operator
    char *tmp2;
    for (int i=0; i<size; i+=2)
    {
        tmp2[i] = tmp[i];
    }
    

    damit du nicht anfängst, so zu programmieren: das funktioniert nicht. sizeof liefert dir hier die größe von tmp, tmp ist ein char*, d.h. sizeof(tmp) == sizeof(char*) , idR "4", sizeof(char) liefert dir immer "1". der wahrscheinlichste (auf dem system, das du verwendest) inhalt von size ist also 4.
    übrigens reicht weiter unten dann tmp[j] = '\0'.

    Nebukat schrieb:

    // Länge der Textdatei ermitteln
        datei.seekg (0, ios::end);
        laenge = datei.tellg();
        datei.seekg (0, ios::beg);
    
        char zeichen[laenge/2];
    

    das wird auch nicht funktionieren, weil laenge/2 erst zur laufzeit berechnet werden kann und in C++ arrays, deren größe erst dann feststeht, mit new[] angefordert werden müssen (und dann mit delete[] freigegeben).

    warum nicht einen container, z.b. std::string ?

    int main()
    {
       ifstream fin("test");
    
       string text;
    
       for (char tmp = fin.get(); fin; fin >> tmp)
       {
          if (fin >> tmp)
             text.push_back(tmp);
       }
    
       cout << text << endl;
    }
    


  • ifstream datei;
      datei.open("Text.txt", ios:: binary);
    
    // Länge der Textdatei ermitteln
       datei.seekg (0, ios::end);
       vector<char> vData(datei.tellg();/2);
       datei.seekg (0, ios::beg);
    
        for(;datei ;datei.get())
            datei.get(vData[i]); //Einlesen jedes zweiten zeichen
    


  • ich will auch meinen Senf dazu geben 😃

    std::ifstream file( "file.txt", std::ios::ate );
    int size = file.tellg();
    file.seekg(0, std::ios::beg);
    char * content = new char[size];
    file.read( content, size );
    char * halfcontent = new char[ size / 2 ];
    for( int i = 0; i < size; i+= 2 )
    {
        halfcontent[ i / 2 ] = content[ i ];
    }
    delete [] content;
    std::cout << halfcontent << std::flush;
    delete [] halfcontent;
    


  • bitte löschen war versehentlich ein doppelpost



  • Habs hingekriegt, vielen Dank an alle!:)



  • Erhard Henkes schrieb:

    Eleganz in C++ bedeutet vermutlich Kapselung, generische Programmierung und raffinierter Einsatz der STL. 😉

    #include <fstream>
    #include <iterator>
    
    template< typename T, typename In >
    struct IncTwice : std::iterator< std::input_iterator_tag, T >
    {
        explicit IncTwice( In p ) : m_p( p ) {}
        IncTwice& operator++()
        {
            ++m_p; ++m_p;   // zwei mal inkrementieren
            return *this;
        }
        T operator*() const { return *m_p; }
        bool operator!=( const IncTwice& b ) const
        {
            return m_p != b.m_p;
        }
    private:
        In m_p;
    };
    template< typename T, typename In >
    IncTwice< T, In > incTwice( In out )
    {
        return IncTwice< T, In >( out );
    }
    
    int main()
    {
        using namespace std;
        ifstream quelle( "input.txt" );
        ofstream ziel( "output.txt" );
        copy(   incTwice< char >( istreambuf_iterator< char >( quelle ) ), 
                incTwice< char >( istreambuf_iterator< char >() ),
                ostreambuf_iterator< char >( ziel ) );
        return 0;
    }
    

Anmelden zum Antworten