Nur jedes zweite Zeichen aus einem File...
-
Hallo liebe Leute!:)
Ich habe ein kleines Problem.
Ich soll eine Datei öffnen, z.B. eine Textdatei, dann soll nur jedes zweite Zeichen aus dem Text berücksichtigt werden und in eine Zieldatei gespeichert werden.
Das ist bestimmt sehr simpel, aber ich kriegs net hin.:(
Momentan hab ich es soweit, daß ich mit getline() Zeile für Zeile des Quelltextes lese per While-Schleife und einem String übergebe.Dummerweise hab ich mit jetzt den Code net auf de Stick gemacht..Mist.
Na ja, vielleicht gehts auch so...Innerhalb der While-Schleife arbeite ich dann mit einem bestimmten String-Pointer(interior?) und ordne in einer for-schleife mit einer SChrittweite von zwei mittels Ziel.put(*i) jedes zweite Zeichen dem Ziel zu.
Leider passiert bei einer ungeraden Zeichenanzahl Mist, denn dann erscheint im Zieltext ein Leerzeichen, könnte wohl was mit dem Zeilenumbruch zu tun haben?
Irgendwie ist mir schon klar, daß es ein Unterschied ist, ob ich eine gerade oder ungerade Anzahl pro Zeile habe.
Aber wie fang ich das ab?Um Tipps wäre ich sehr sehr dankbar!:)
-
ich hätte da einen vorschlag:
wenn du doch jede zeile einlesen kannst, kannst du sie doch auch in einem char-Feld oder einem string speichern, welches du dann mittels for-schleife durchläufst und jedes 2. zeichen daraus entziehst:
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]; }oder ohne 2 tmp-Variablen in einer Schleife int j = 0; for (int i=0; i<size; i+=2) { tmp[j] = tmp[i]; j++ } // und damit der string auch am ende abgeschlossen ist fügen wir noch das ein: tmp[j+1] = '\0';
-
Das wäre jetzt unter C, oder?
Da muss ich das File doch aber per fopen aufmachen, oder?
dann muss ich den Inhalt des Files doch aber einem String zuordnen und irgendwie hat das net geklappt, das was du gemailt hast hatte ich im Sinn, wenn auch net so ausgereift, da ich ja noch net so die Ahnung habe.Ich hab das File so aufgemacht:
File *f1;
f1 = fopen(quelldateiname; "rb");Da ich den Inhalt von f1 net mit einer For-SChleife durchtippeln konnte, weiss jedenfalls net wie,
da habe ich dann versucht f1 einem string zuzuweisen, aber das verträgt sich von den typen her net.Möglicherweise, oder sehr wahrscheinlich mach ich was ganz grundlegendes falsch.^^
-
Okay...
hm...
dann probiers doch mal mit streamsifstream 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 wirdNach 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; }