explode (aus PHP) in C++, bzw. lange Variable unterteilen



  • Hallo Leute,

    ich möchte aus einer langen Variable, die in einer Textdatei gespeichert ist, mehrere kleine machen.
    Der Inhalt der Datei sieht folgendermaßen aus:

    0|test|123|Hello world|18.6.2012;
    1|variable|456|Hallo Welt|18.6.2012;
    

    in PHP geht das ganze ja per "explode".

    $items = explode(";", $content);
    //content ist der Inhalt der Textdatei, der ausgelesen wird
    
    list($check, $var, $zahl, $text, $date) = explode("|", $item);
    

    Ist das auch in C++ umsetzbar??



  • Natürlich ist das in C++ umsetzbar. Man muss sich halt eine entsprechende Funktion dafür schreiben.



  • #include <iostream>
    #include <string>
    #include <sstream>
    #include <algorithm>
    #include <iterator>
    #include <vector>
    
    namespace my {
    	struct actype : std::ctype< char > {
    		actype(): std::ctype< char >(get_table()) {}
    		static std::ctype_base::mask const* get_table() {
    			static std::ctype_base::mask* rc = 0;
    
    			if( !rc ) {
    				rc = new std::ctype_base::mask[std::ctype<char>::table_size];
    				std::fill_n(rc, std::ctype<char>::table_size,
    				std::ctype_base::mask());
    				rc['|']  = std::ctype_base::space;
    				rc['\n'] = std::ctype_base::space;
    			}
    			return rc;
    		}
    	};
    
    	std::vector< std::string > split( std::string input )
    	{
    		std::istringstream iss( input );
    		iss.imbue(std::locale(std::locale(), new my::actype));
    
    		std::vector<std::string> tokens;
    		std::copy(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>(), std::back_inserter<std::vector<std::string> >(tokens));
    
    		return tokens;
    	}
    }
    
    int main() {
    
        std::vector< std::string > tokens = my::split( "0|test|123|Hello world|18.6.2012" );
    
    	for( std::vector<std::string>::iterator i = tokens.begin(); i!= tokens.end(); ++i )	{
    		std::cout << *i << '\n';
    	}
    }
    


  • #include <vector>
    #include <string>
    
    template<typename T> bool DefaultCompareFunc(T const &first, T const &second)
    {
        return first == second;
    }
    
    template<typename T, template<typename T, typename...> class Container, typename FuncType>
        std::vector<Container<T> > GetSeparated(Container<T> const &in, T comp_value, FuncType comp_func)
    {
        std::vector<Container<T> > ret;
    
        typename Container<T>::const_iterator start_iter = in.begin(), end_iter = in.begin();
        while(end_iter != in.end())
        {
            if(comp_func(*end_iter, comp_value))
            {
                if(start_iter != end_iter)
                {
                    ret.push_back(Container<T>(start_iter, end_iter));
                }
                start_iter = end_iter;
                ++start_iter;
            }
            ++end_iter;
        }
        if(start_iter != end_iter)
        {
            ret.push_back(Container<T>(start_iter, end_iter));
        }
    
        return ret;
    }
    
    template<typename T, template<typename T, typename...> class Container>
        std::vector<Container<T> > GetSeparated(Container<T> const &in, T comp_value)
    {
        return GetSeparated(in, comp_value, DefaultCompareFunc<T>);
    }
    
    int main()
    {
        std::string content = "0|test|123|Hello world|18.6.2012;\n1|variable|456|Hallo Welt|18.6.2012;"; 	
        std::vector<std::vector<std::string> > tokens;
    
        std::vector<std::string> items = GetSeparated(content, ';');
        for(int i = 0; i < items.size(); ++i)
        {
            tokens.push_back(GetSeparated(items[i], '|'));
        }
    }
    


  • elogant 😉



  • 😮

    std::vector<std::string> split(std::string s, char delim)
    {
        std::istringstream iss(std::move(s));
        std::vector<std::string> result;
    
        while(std::getline(iss, s, delim))
            result.push_back(std::move(s));
    
        return result;    
    }
    


  • Oha
    Danke!
    Damit muss ich mich erstmal auseinandersetzen.
    ist n bisschen mehr als ich erwartet habe 😉

    LG



  • soo
    jetzt habe ich mich damit auseinandergesetzt...
    und ich verstehe so ziemlich gar nichts 😉

    Egal wie ich den Script von wxSkip in meinen hereineditiere, bekomme ich tausende Fehlermeldungen.

    Der von Swordfish funktioniert so weit. Aber ich kann nicht genau nachvollziehen wie.
    Sind die Werte aus meiner Datei

    0|test|123|Hello world|18.6.2012;
    

    alle in dem Vector "tokens" abgespeichert?
    und wie kann ich dann mit diesen Werten weiterarbeiten?
    Ich kann den Code insgesamt nicht ganz nachvollziehen.

    Ich bin eigentlich auch noch ein blutiger Anfänger, was C++ angeht... 😉



  • Ja, sie sind in tokens gespeichert. Du kannst tokens wie ein Array verwenden.

    tokens[0] // erste Element
    tokens[1] // zweite Element
    
    tokens.size() // Anzahl der Elemente
    

    Sprich folgendes macht genau das gleiche:

    for (int i = 0; i < tokens.size(); ++i)
    {
     std::cout << tokens[i] << "\n";
    }
    


  • JanK411 schrieb:

    Egal wie ich den Script von wxSkip in meinen hereineditiere, bekomme ich tausende Fehlermeldungen.

    Welche? Welchen Compiler hast du?



  • #include <boost/algorithm/string.hpp>
    
    std::vector<std::string> items;
    boost::split(items, content, boost::is_any_of("|"));
    

    sollte genau das tun


Anmelden zum Antworten