string einlesen, speichern und rückwärts ausgeben



  • hallo,

    hoffe jemand kann mir helfen.

    ich soll nen string einlesen, diesen abspeichern und dann rückwärts ausgeben bzw. in umgekehrter reihenfolge:

    also: programmieren fällt mir schwer (eingabe) schwer mir fällt programmieren (ausgabe)

    das ganze soll als klasse implementiert werden.

    ich wollte das ganze so lösen:

    einlesen (enweder in nen string und dann wort für wort in nen vector speichern) oder gleich in nen vector einlesen.

    dann das letzte element in dem vector in nen neuen vector kopieren als erstes element, das nächste an zweite stelle etc. und dann halt das ganze wieder ausgeben (die performance ist wohl nicht gut aber das ist mir wurst, hauptsache das programm macht was es machen soll 🙂

    wie ich ne class erstelle ist mir klar

    nur funzt das ganze auch auf diese art und weise? bzw. hab auch dran gedacht das ganze in nem string stehen zu lassen (den satz) und von hinten her den string in nen anderen string zu kopieren (dürfte wohl schneller gehen) aber der code scheint mir dann doch etwas schwieriger (muss ich wohl mit iteratoren arbeiten oder?)

    gruß

    wandiii 🙂



  • Die Performance ist bei so nem Programm egal und wird auch häufig von Anfängern überschätzt. Es geht erst mal drum, ein Gefühl fürs Programmieren zu entwickeln, dann kannst du immer noch genug rumoptimieren. Das heißt, du kannst es so machen, wie du es dir überlegt hast.



  • typedef boost::tokenizer< boost::char_separator<char> > tokenizer;
    boost::char_separator<char> sep(" ");
    tokenizer tok("Dies ist ein Test");
    
    std::vector<string> tokens;
    std::copy(tok.begin(), tok.end(), std::back_inserter(tokens));
    std::copy(tokens.rbegin(), tokens.rend(), std::ostream_iterator<string>(cout, " "));
    

    (ungetestet, geht sicher auch einfacher.)



  • Konrad Rudolph: Ich bezweifle, dass Wandiii boost installiert hat 😉



  • Michael E. schrieb:

    Konrad Rudolph: Ich bezweifle, dass Wandiii boost installiert hat 😉

    Ja, Du hast recht. Eine Lösung mit find ist da wahrscheinlich besser, obwohl solch ein Tokenizer schon was hermacht. Abgesehen davon klappt der Code bei mir nicht ganz (wenn man vom fehlenden String-Konstruktor mal absieht) -- es werden irgendwelche kryptischen Zeichen eingefügt.



  • Er selbst hat die einfachste Lösung ja schon fast gefunden 🙂 getline tokenizet (^^) genug 😉



  • hauptsache das programm macht was es machen soll

    naja dann hab ich hier nen einfachen Code:

    vector<string> tab(1);
    int i = 1;
    string s;
    //Variablen etc.
    
    tab[0] = "";
    //damit die Zählung bei 1 beginnt (siehe Text)
    
    while(s != "0"){
                    cout << i << ". Wort des Satzes eingeben. Ende mit 0. ";
                    cin >> s;
                    //Abfrage der Wörter und speichern in s
    
                    if(s != "0") tab.push_back (s);
                    // s prüfen (Ende mit 0) und in der Tabelle tab speichern                
    
                    i++;
                    }
    
        for(size_t j = (tab.size()-1); j > 0; j--){
               cout << tab[j] << " ";
    //Wörterreihenfolge rückwärts ausgeben
    

    is getestet! Programm frägt die einzelnen Worte ab und speichert sie. Gibt sie danach (zumindest bei mir) rückwärts aus.
    nach dem Beispiel mit

    programmieren fällt mir schwer

    hatte ein paar Probleme mit meinem Compiler deshalb hab ich die Zählung bei 1 starten lassen. (einfach 1. Wert "" gesetzt) 😃

    is nicht optimal denk ich aber
    1. es funzt und das wolltest du doch?
    2. ich bin c++ totalanfänger 😉 und hab's noch nicht so drauf...



  • danke für die schnellen antworten 🙂 werd das ganze dann mal testen, muss aber erstmal nen programm schreiben, dass ne textdatei einliesst, abspeichert(im speicher als string) und mit ner umrahmung wieder ausgibt 🙂 ^^

    das bekomm ich aber glaube allein hin, das mit datei einlesen hatten wir zwar noch net aber da hab ich ifstream im netz gefunden.

    nur ne kleine anfrage wegen ifstream: wie kann ich dort angeben wo die datei liegt?

    wenn ich bei ifstream die datei so("text.txt")angebe, holt der mir die aus dem projektverzeichnis, und bei ("c:\text.txt") hat der die net von C:\ gelesen. muss man das irgendwie anders eingeben? 😃 bzw. wenn man das ganze variable gestallten will, dann kann ich doch statt ("text.txt") ne variable (string) angeben und vorher lass ich den benutzer halt in den string den dateinamen eingeben, sollte doch so funktionieren oder? na ja teste es gleich mal selbst 😃



  • Wandiii schrieb:

    wenn ich bei ifstream die datei so("text.txt")angebe, holt der mir die aus dem projektverzeichnis, und bei ("c:\text.txt") hat der die net von C:\ gelesen.

    Du musst den String korrekt escapen. Bei "\t" denkt der Compile, das solle ein Tabulatorzeichen sein. Du musst also schreiben "C:\\test.txt", dann klappt es.



  • hmmm irgendwie funzt das net so richtig 🙂

    ich erzeuge nen string

    les dort meinen dateinamne ein

    und geb dann an z.b. ifstream file(datei);
    .
    .
    .

    dann bringt mir der kompiler die fehlermeldung:
    'std::basic_ifstream<_Elem,_Traits>::basic_ifstream(const char *,std::_Iosb<_Dummy>::openmode,int)': Konvertierung des Parameters 1 von 'std::string' in 'const char *' nicht möglich
    das sternchen hat wohl was mit zeiger zu tun oder bei const char *? leider haben wir damit noch gar nix gemacht und werden wohl auch nix damit machen ^^ wie kann nun nen variablen dateinamen bei ifstream angeben?



  • der ifstream-Konstruktor kann leider keinen String annehmen. Ruf ihn so auf:

    ifstream file(datei.c_str());
    

    ('datei' sei der String mit dem Dateiname.)



  • Das ist eine der kleinen Inkonsistenzen in der C++ Standardbibliothek, mit der viele erfahrene Programmierer zu leben gelernt haben - std::fstream erwartet den Dateinamen nicht als std::string, sondern als const char* (String im C-Stil). Und die Lösung des Problems ist einfach - wandle deinen String in einen char* um:

    ifstream file(datei.c_str());// die Methode c_str() liefert den Datenpuffer des Strings als char-Array
    


  • vielen dank: hab auch folgenden nützlichen code gefunden

    int main() {
    char dateiname_lesen[10], dateiname_schreiben[10];
    // der Dateiname der Datei, von der wir lesen wollen
    cout << "Dateiname lesen: ";
    cin >> dateiname_lesen;
    // der Dateiname der Datei, in die wir schreiben wollen
    cout << "Dateiname schreiben: ";
    cin >> dateiname_schreiben;
    // Dateien zum lesen/schreiben oeffnen
    ifstream datei_lesen;
    datei_lesen.open( dateiname_lesen );
    ofstream datei_schreiben;
    datei_schreiben.open( dateiname_schreiben );
    // Lies Zeichen von der ersten Datei, bis Datei zu Ende
    // Die Datei wird Zeichenweise gelesen
    while( !datei_lesen.eof() ) {
    char z = datei_lesen.get();
    // rot13-"verschluesselung"
    if( z >= 'A' and z <= 'Z' ) {
    z = (z - 'A' + 13) % 26 + 'A';
    }
    datei_schreiben.put(z);
    }
    // Dateien wieder schliessen
    datei_lesen.close();
    datei_



  • Jetzt solltest du nur noch die Dateinamen in std::string's lesen statt in char-Arrays - selbst wenn du DOS-Namen (8.3) ohne Pfad-Angaben verwendest, dürftest du schon Probleme mit dem verfügbaren Platz für die Eingaben haben.

    (und cin kann nicht überprüfen, wieviel Platz es zum Schreiben hat)



  • ja stimmt, leider wird in vielen ältern büchern bei vectoren, chars etc. immer ne explizite größe angeben 😃 was wirklich zu problemen führen kann.

    den code verwende ich auch net sondern ich versuch mir jetzt selbst was zusammen zu basteln



  • so ich hätte nun noch ne kleine fragen, wegen dem ersten programm:

    ich hab es jetzt geschafft, die textdatei in nen vector einzulesen (das ganze in eine funktion gepackt), dann frag ich noch die größe des vektors ab und lass mir die max. zeilenbreite dazu berechnen.

    nun soll noch ne umrahmung dazu. nehmen wir mal an 1 leerzeichen oben, unten und an jeder zeite und ganz aussen sternchen.

    die erste zeile ausgeben ist ja einfach alles sterne, die zeite zeile am rand sterne und in der mitte leerzeichen

    nächste zeile (erste textzeile) wieder stern am rand, dann berechne ich mir mit leervor = (maxstringlaenge-lange aktueller string +2) / 2 die leerzeichen vor dem string (bei ungeradem ergebnis, nehm ich nur den ganzzahlteil, weil dann kann ich die textzeile eh nicht ganz zentrieren)(text) dann geb ich den textstring aus, dann berechne ich (maxlaenge + 2)-leervor - textstring.

    das ganze sollte doch so funktionieren oder? 😃



  • CStoll schrieb:

    Das ist eine der kleinen Inkonsistenzen in der C++ Standardbibliothek

    Inkonsistent? IMHO wird konsistent auf std::string verzichtet.



  • so, hab noch so meine kleine probleme mit der zweiten aufgabe:

    ich soll ne Klasse implementieren, welche nen textstring einliest, abspeichert und dann rückwärts ausgibt.

    ich definiere alse ne class string_verarbeitung

    private würd ich halt den string zeile; setzten

    dann würde ich public: einmal ne funktion schreiben, welche von der tastatur in den string einliest und somit auch abspeichert

    nun soll das ganze aber rückwärts ausgegeben werden, ich hab mal wo gelesen, dass ich mich durch iteratoren durch nen string hangeln kann, dann würde ich die größte des strings abfragen, dann den iterator dorthin setzten und solang durch den string gehen bis ich auf ein leerzeichen treff, das würd ich ausgeben usw. bis mein iterator bei 0 angekommen ist. aber wie mach ich das ganze?

    hoffe einer kann mir um die uhrzeit noch helfen 😃


Anmelden zum Antworten