"Rohdatentyp"



  • Antwort auf deine ursprüngliche Frage:
    Man verwendet für sowas std::vector<char> bzw. std::vector<unsigned char>



  • cooky451 schrieb:

    Wie würde man zB. folgenden Ausdruck mit C++ realisieren?

    char bar[] = 
      "Hallo, ich bin ein Test-String\n"
      "Really!\n"
      "\n";
    

    Äh.
    So?

    char const bar[] = 
      "Hallo, ich bin ein Test-String\n"
      "Really!\n"
      "\n";
    


  • Also eigentlich spricht trotzdem nicht gegen char * mit einer Variablen als Längenangabe... Und eigentlich spricht auch nix gegen std::string..
    Nur weil der Inhalt vielleicht nicht unbedingt als Zeichen interpretiert werden sollte, heißt das ja nicht, dass man nicht trotzdem alles dort reinwerfen kann, was der char-Wertebereich hergibt. Zumindest soweit die Theorie...



  • std::string kann man aber über string.data() nicht beschreiben, der Datentyp soll einen char* und nicht nur einen const char* liefern können.

    @hustbaer
    Und jetzt das ganze noch mal mit std::vector<char> und ich bin glücklich 😃


  • Mod

    cooky451 schrieb:

    @hustbaer
    Und jetzt das ganze noch mal mit std::vector<char> und ich bin glücklich 😃

    #include <iterator>
    #include <vector>
    
    template<class InputIterator, class OutputIterator>
      OutputIterator strcpy ( InputIterator first, OutputIterator result )
    {
      while (*first) *result++ = *first++;
      return result;
    }
    
    int main()
    {
      std::vector<char> test;
      strcpy("Hallo Welt!\n",std::back_inserter(test));
    }
    


  • Vielleicht hast du ja auch einen konkreten Anwendungsfall, so dass man dir gezielter helfen kann.



  • SeppJ schrieb:

    cooky451 schrieb:

    @hustbaer
    Und jetzt das ganze noch mal mit std::vector<char> und ich bin glücklich 😃

    #include <iterator>
    #include <vector>
    
    template<class InputIterator, class OutputIterator>
      OutputIterator strcpy ( InputIterator first, OutputIterator result )
    {
      while (*first) *result++ = *first++;
      return result;
    }
    
    int main()
    {
      std::vector<char> test;
      strcpy("Hallo Welt!\n",std::back_inserter(test));
    }
    

    ach du heilige scheiße... nimm doch in gottes namen einfach char* 😃


  • Mod

    Aufpasser schrieb:

    ach du heilige scheiße... nimm doch in gottes namen einfach char* 😃

    Und dann baut er ein Speicherleck nach dem anderen, kommt mit der Übergabe an Funktionen nicht zurecht und und und...

    Das alles um sich die obigen drei Zeilen Code zu sparen?



  • Oder ich schreib mir ne Wrapper-Klasse für std::vector? Oder ich bleibe einfach bei --C 😃



  • SeppJ schrieb:

    Aufpasser schrieb:

    ach du heilige scheiße... nimm doch in gottes namen einfach char* 😃

    Und dann baut er ein Speicherleck nach dem anderen, kommt mit der Übergabe an Funktionen nicht zurecht und und und...

    Das alles um sich die obigen drei Zeilen Code zu sparen?

    Ist aber schon interessant, dass du jedem unterstellst, mit C++-Arrays nicht ordentlich umgehen zu können und ihm stattdessen nahelegst ein Template zu programmieren....



  • Warum wird eigentlich prinzipiell immer dazu geraten std::vector zu nehmen und nicht boost::array bzw std::array?

    Seitdem ich boost::array entdeckt hab, sind 50% meiner STL-Vektoren aus dem Code geflogen. Meistens ist es deutlich effektiver ein bischen zu viel Speicher zu verbrauchen (der meistens ja auch noch auf dem Stack liegt ... und Vektor verschwendet meistens noch mehr) als permnanent Speicher zu allozieren.
    Mir ist jedenfalls ein guter Geschwindigkeitszuwachs aufgefallen.

    Dass das Ganze natürlich nur Sinn macht, wenn man ungefähr den Speicherbedarf einschätzen kann ist klar ... 😉



  • std::array kenne ich gar nicht.. das gibts?^^
    Kann das auf www.cplusplus.com auch nicht finden..

    Aber mal abgesehen davon..

    class MyBuf
    {
    private:
      std::vector<char> m_vector;
    public:
      MyBuf()
      {
      }
      MyBuf(std::string& text)
      {
        *this = text;
      }
      MyBuf(char *text)
      {
        *this = text;
      }
      void operator = (std::string& text)
      {
        m_vector.resize(text.length() + 1);
        strcpy(m_vector.data(), text.c_str());
      }
      void operator = (char *text)
      {
        std::string l_tmp = text;
        *this = l_tmp;
      }
      char *data()
      {
        return m_vector.data();
      }
      void resize(std::size_t size)
      {
        m_vector.resize(size);
      }
      std::size_t size()
      {
        return m_vector.size();
      }
    };
    

    Total ehm.. naja.. Klasse? 😃



  • Ich denke er meint std::tr1::array, was dann soviel ist wie boost::array.



  • Alternativ so:

    #include <iostream>
    #include <vector>
    
    const char * const txt = "Hallo Welt!";
    
    static size_t len(const char * c)
    {
      size_t len;
      for (len = 0; *c++; ++len)
        ;
      return len;
    }
    
    int main()
    {
      std::vector<char> buf(txt, txt + len(txt) + 1);
      std::cout << &buf[0] << '\n';
    }
    


  • Das ist einfach weil strlen() zu low wär 😉



  • Wenn dir strlen() zu low ist, dann wären das noch zwei Möglichkeiten :

    #include <iostream>
    #include <vector>
    
    std::vector<char> cstr2vec(const char * cstr)
    {
      std::vector<char> vec;
      for (; *cstr; ++cstr)
        vec.push_back(*cstr);
      vec.push_back('\0');
      return vec;
    }
    
    int main()
    {
      {
        const char anf [] = "Hallo Welt!";
        const char end [] = "";
    
        std::vector<char> buf(anf, end);
        std::cout << &buf[0] << '\n';
      }
      {
        std::vector<char> buf(cstr2vec("Hallo Welt!"));
        std::cout << &buf[0] << '\n';
      }
    }
    

    Wenn du dich nur an strlen als C-Funktion störst, dann geht auch:

    std::string("Hallo").length()
    

    Das mach aber auch nichts anderes.



  • Für String-Literale spricht natürlich auch in C++ nichts dagegen, const char* zu nehmen. Aber die const -Qualifizierung sollte man nicht vergessen.

    cooky451, vielleicht ein paar Verbesserungsvorschläge für deine Klasse:

    • std::vector besitzt keine Memberfunktion data() .
    • Mach deine Methoden const -korrekt. Sowohl die Memberfunktion selbst als auch ihre Parameter sind teilweise unnötig eingeschränkt durch Zeiger/Referenzen auf veränderbare Objekte.
    • Im Kopierkonstruktor den Zuweisungsoperator aufzurufen ist eher unüblich. Mach es lieber umgekehrt mit dem Copy-and-Swap-Idiom.
    • Der Umweg von char* über std::string ist unnötig ineffizient. Auch hier könntest du mit dem umgekehrten Weg besser fahren (unter Benutzung von std::string::c_str() ).


  • Hm.
    Kann Boost.Assign vielleicht vector<char> = (string-literal) ?


  • Mod

    #include <iostream>
    #include <vector>
    
    const char txt[] = "Hallo Welt!";
    
    template<std::size_t N>
    std::vector<char> str2vec(const char (&str)[N])
    {
        return std::vector<char>( str, str + N );
    }
    
    int main()
    {
      std::vector<char> buf( str2vec( txt ) );
      std::cout << &buf[0] << '\n';
    }
    

  • Mod

    hav a break schrieb:

    const char anf [] = "Hallo Welt!";
        const char end [] = "";
    
        std::vector<char> buf(anf, end);
    

    Das ist ziemlich undefiniert.


Anmelden zum Antworten