"Rohdatentyp"
-
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
-
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*

-
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 dieconst-Qualifizierung sollte man nicht vergessen.cooky451, vielleicht ein paar Verbesserungsvorschläge für deine Klasse:
std::vectorbesitzt keine Memberfunktiondata().- 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*überstd::stringist unnötig ineffizient. Auch hier könntest du mit dem umgekehrten Weg besser fahren (unter Benutzung vonstd::string::c_str()).
-
Hm.
Kann Boost.Assign vielleichtvector<char> = (string-literal)?
-
#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'; }
-
hav a break schrieb:
const char anf [] = "Hallo Welt!"; const char end [] = ""; std::vector<char> buf(anf, end);Das ist ziemlich undefiniert.
-
Aufpasser schrieb:
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....
Er unterstellt nur, dass jeder Fehler macht, und wer viele Fehler macht, macht die auch mal bei C++-Arrays - und das führt dann häufig zu Speicherlecks, weil das eben einer der Schwachpunkte von C++-Arrays gegenüber std::vectoren ist.
-
hustbaer schrieb:
Hm.
Kann Boost.Assign vielleichtvector<char> = (string-literal)?#include <vector> #include <iostream> #include <iterator> #include <algorithm> #include <boost/assign/list_of.hpp> int main() { using namespace std; vector<char> v = boost::assign::list_of<char>().range("Hallo Welt!"); copy(v.begin(), v.end(), ostream_iterator<char>(cout)); return 0; }
-
Also um Speicherlecks mache ich mir weniger Sorgen, bei meinen Mini-Projekten (< 5k Zeilen) fällt sowas doch recht schnell auf. Allerdings versuche ich mich gerade vollständig in C++ zu denken und möchte somit möglichst den "C-Weg" vermeiden - und hoffe einfach dass das nicht zu übertrieben wirkt

@Nexus
Die Klasse war eigentlich eher scherzhaft gemeint aber scheinbar ist das wohl gar nicht so schlecht?!?^^Naja ein paar Fragen hätte ich da noch zu deinen Verbesserungsvorschlägen:
1. "Const-Correctness" habe ich mir hier ( http://www.possibility.com/Cpp/const.html ) mal durchgelesen allerdings meckert der VS compiler (warning C4114: Der gleiche Typqualifizierer wurde mehrmals verwendet) bei " const std::string const& text ". Was denn nun? Ist das wirklich falsch?2. Copy-and-Swap-Idiom verstehe ich nicht so richtig, eine Erklärung und ein kurzes Beispiel wären eventuell hilfreich.. (Finde da irgendwie immer nur Beschreibungen im Zusammenhang mit exceptions.. und diese verstehe ich peinlicherweise auch nicht wirklich..)
@hav a break
Ich verstehe überhaupt nicht was dein Code mir sagen soll.. also.. irgendwie hat das alles ziemlich wenig mit dem gefragten zu tun.. oder übersehe ich hier etwas ganz grobes? Was soll das zB. für eine Funktion sein?:hav a break schrieb:
Alternativ so:
static size_t len(const char * c) { size_t len; for (len = 0; *c++; ++len) ; return len; }Und warum nutzt Du da nicht einfach strlen() ?