String bearbeiten (Leerzeichen bzw Zeilenumbruch entfernen)



  • Hallo !

    Bekomme nach Manipulation eines Strings einen neuen Substring in folgender Form heraus (parse auch html Datei):

    substring:
    InhaltdesStrings

    (also mit Leerzeile) möchte das Ganze allerdings in Form

    substring: InhaltdesStrings haben !

    Hab schon folgendes versucht:

    std::string::size_type i = tmpString.find(' ');
    
    while(i != std::string::npos)
    {
        tmpString.erase(i, 1);
        i = tmpString.find(' ', i);
    }
    

    Die Strings werden dann in eine text Datei geschrieben und schauen im vi
    wie folgt aus:

    TEXT^M
    ;^M
    TEXT^M
    

    Wie kann ich das am besten lösen dass alles in einer Zeile steht ?

    Danke und mfg



  • genauso, wie du nach ' ' suchst kannst du auch nach '\n' suchen (Zeilenumbruch).
    Vll ist es aber einfacher/schneller, wenn du das so machst:

    std::string tmp;
    for(std::string::iterator it = DeinString.begin(), et = DeinString.end();it!=et;++it)
    {
        if( *it != '\n' && *it != ' ')
            tmp+=(*it);
    }
    DeinString.swap(tmp);
    


  • Danke für die schnelle Antwort aber so ähnlich hab ich es auch schon mal probiert (\n entfernen) erhalte aber mit deiner Methode aus

    tmpStringZS: 
                        TEXT
                    </td>
    

    dann diesen String (also wieder mit Leerzeile und sogar Leerzeichen (</td> wird
    vorher entfernt)

    tmpString: 
                        TEXT
    

    Hat wer eine Idee ?

    mfg



  • du könntest die datei anschließend nochmals einlesen, in einem 2d-array speichern und dann alle zeichen außer ' ' und '\n' in ein neues array schreiben und das dann in eine textdatei.

    ich schreib mal ein codebeispiel.

    mfg,
    andi01.



  • so könnte es zB gehen(is aber noch ungetestet!):

    #include<iostream>
    #include<windows.h>
    #include<conio.h>
    #include<string>
    #include<fstream>
    using namespace std;
    
    int main()
    {
    	ifstream myfile(/*Pfad deiner datei*/);
    	int zeilenanzahl=0;
    
    	//auslesen
    	myfile.seekg(0,ios::beg);
    	char zeile[500] [1025];
    	int a=0;
    	while(!myfile.eof())
    	{
    		myfile.getline(zeile[a],1024);
    		zeilenanzahl++;
    		a++;
    	}
    	myfile.close();
    	//in neues array ohne leerzeichne/ zeilenumbrüche schreiben:
    	char datei_neu[100000];
    	for(int a=0;a<zeilenanzahl;a++)
    	{
    		for(int b=0;b<1025;b++)
    		{
    			if(zeile[a][b]!=' '&&zeile[a][b]!='\n')
    			{
    				zeile[a][b]=datei_neu[b];
    			}
    		}
    	}
    	//in neue datei schreiben
    	ofstream neue_datei(/*Dateipfad*/);
    	neue_datei<<datei_neu;
    	neue_datei.close();
    
    	getch();
    }
    

    ist vielleicht nicht die eleganteste lösung, aber die einzige die mir im moment einfällt ist die datei nochmal zu überschreiben.

    mfg,
    andi01.



  • Danke, aber ich möchte einfach nur den String so bearbeiten dass die überschüssigen Zeichen wegfallen.

    Ich schreib auch mal wie ich die Datei in einen String konvertiert habe:

    stringstream tmpStream;
    ifstream inputFile(filePathRead.c_str());
    
    // copy the whole file to a single string
    tmpStream << inputFile.rdbuf(); 
    inputFileString = tmpStream.str();
    
    inputFile.close();
    

    In inputFileString steht nun der gesamte Inhalt der Datei !

    mfg



  • naja das is ja noch einfacher:

    string dein_string="abc def ghi";
    string neu;
    
    for(int a=0;a<dein_string.length();a++)
    {
    if(dein_string[a]!=' '&&dein_string[a]!='\n')
    {
    neu[a]=dein_string[a];
    }
    }
    

    damit schreibste jedes zeichen deines strings das kein leerzeichen oder zeilenumbruch ist in einen neuen string den du dann in die datei schreiben kannst.

    d.h. zuerst tust du das was du von leerzeichen und zeilenumbrüchen befreien willst in dein_string, dann speicherst du einfach neu per ofstream in die textdatei. so befreit man den string von leerzeichen und so.
    mfg,
    andi01.



  • @andi01: was steht in neu?

    @leon22: Der Code von Gilder funktioniert einwandfrei. Du solltest mal deinen kompletten Versuch zeigen. Denn irgendwie erzählst du etwas und dein Code macht was anderes...



  • hatte einfach die rehenfolge vertauscht, jetzt stimmt der code oben, habs ausgebessert 😃

    edit: habs jetzt geschafft, code steht auf der nächsten seite!

    mfg,
    andi01.



  • andi01 schrieb:

    jetzt sollte es aber funktionieren 🙂

    Nein.
    Der Index in neu ist ja nicht immer gleich vom alten string. (gleich oder kleiner. Aber du kannst das Zeichen ja einfach anfügen...)

    Zudem ist es bei solchen Sachen (erstrecht wenn man sich nicht 110% sicher ist) sinnvoll, einfach ein kleines Testprogramm zu schreiben und es selber auszuprobieren. Bevor man es postet 😉



  • jo hab ich auch grade beim testen gemerkt, ich versuche mal den fehler noch zu beheben.



  • juhu, geschafft:
    der code funktioniert!!!

    #include<iostream>
    #include<windows.h>
    #include<conio.h>
    #include<fstream>
    #include<string>
    using namespace std;
    
    int main()
    {
    string dein_string="abc\n def ghi"; 
    string neu; 
    
    for(int a=0;a<11;a++) 
    { 
    	if((dein_string[a]!=' ')&&(dein_string[a]!='\n')) 
    	{ 
    	neu+=dein_string[a]; 
    	}
    }
    

    mfg,
    andi01.



  • #include <algorithm>
    #include <string>
    
    template<typename TChar>
    void trim_string(std::basic_string<TChar> &str, TChar to_trim)
    {
    	typedef std::basic_string<TChar> this_string;
    
    	this_string::iterator end=str.end();
    	end = std::remove( str.begin(), end, to_trim );
    	this_string::size_type new_length = this_string::size_type(std::distance(str.begin(), end));
    	str.resize(new_length);
    }
    
    int main()
    {
    	std::string x = "asdkjasd asjhd asdasd a d d f ";
    	trim_string(x, ' ');
    	trim_string(x, 'a');
    	trim_string(x, 'k');
    }
    

    bb



  • unskilled schrieb:

    this_string::size_type(std::distance(str.begin(), end));
    

    Da fehlt 'n typename.
    Ich liefer auch mal einen Vorschlag ab:

    template<typename Container>
    void remove(Container& c, const typename Container::value_type& value)
    {
        c.erase(std::remove(c.begin(), c.end(), value), c.end());
    }
    


  • Guter Vorschlag, Ryuzaki!

    Statt const value_type& kannst du allerdings direkt const_reference nehmen.



  • hmm... ok, sieht echt ein wenig kürzer aus ;o)
    und sollte so gar noch ein wenig schneller sein ^^

    bb


Anmelden zum Antworten