Daten mit Terminating Zero formatieren
-
Hey,
ich muss binäre Daten versenden, da die Befehle als Binärdaten codiert sind.
Das wäre alles kein Problem, aber der Aufbau des Buffers macht mir Probleme. Ich hatte anfangs versucht mit std::stringstream alles zusammen zu bauen, jedoch hat std::stringstream meine \0 rausgekillt, was die Befehle zerstört hat.
Auch mit sprintf konnte ich das Problem nicht lösen.
Wie kann ich das am besten umsetzen? Ich bräuchte im Prinzip sowas:
char buf[1024]; addToBuf(buf, "\10\0\0\0\1\3"); addToBuf(buf, std::string("HELLO").c_str()); addToBuf(buf, "\10\10\0");Ideen für eine möglichst schöne Lösung?

-
Ich brauche mehr Details. Dein Beispiel rechtfertigt stringstream gar nicht.
<<'\0'
müßte gehen. Oder in einem std::string sammeln. Oder write nehmen.
-
Du darfst halt keine C-Strings benutzen. Also alles wo implizit die Größe von einem Literal bestimmt wird. Da kann dein addToBuf von der API her schon gar nicht funktionieren.
char str[] = "\10\10\0\1\3"; std::string s(str, str + sizeof(str)-1);oder eben
std::stringstream sstr << "\10\10" << '\0' << "\1\3";
-
std::stringstream strm; strm << "Blub\0\0\0\0\0\13" << 1001 << "bla"; sock.write(strm.str().c_str(), strm.str().size());Versende ich dies nun, dann kommt auf der Gegenseite folgendes an:
42 6c 75 62 31 30 30 31 62 6c 61 Blub1001 bla
Die 0 ist nicht mehr zu sehen und anscheinend verloren gegangen.
Sie gehört aber dazu und das ist das Problem, was es zu lösen gilt. Deswegen frage ich hier um Hilfe.Ich nutze std::stringstream, da neben den Binären Befehlen auch "normale" Zahlen und Strings vorkommen können, die so bequem umgewandelt werden.
Compiler ist MS Visual Studio 2010.
-
.... schrieb:
std::stringstream strm; strm << "Blub\0\0\0\0\0\13"Hier lädst Du nur
strm << "Blub"
denn am ersten '\0' hört für den op<< dein Eingabestring auf.strm << "Blub" <<'\0'<<'\0'<<'\0'<<'\0'<<'\0'<<'\13'Oder die addToBuf so machen, daß sie Stringliterale ihrer sizeof nach schreibt und nicht bis zum '\0'.
template<size_t size> void addToBuf(char*& buf,char const (&str)[size]){ memcpy(buf,str,size-1); buf+=size-1; } void addToBuf(char*& buf,char const *str){ size_t len=strlen(str); strcpy(buf,str,len); buf+=len; }char buf[1024]; char* end=buf; addToBuf(end, "\10\0\0\0\1\3"); addToBuf(end, std::string("HELLO").c_str()); addToBuf(end, "\10\10\0"); socket.write(buf,end-buf);eklig. Lieber in einem std::string oder vector<char> oder stringstream sammeln.
template<size_t size> void addToBuf(stringstream& out,char const (&str)[size]){ out.write(str,size-1);//oder so. lange nicht mehr write benutzt }Oder noch cooler:
struct StringLiteral{ char const* start; char const* end; template<size_t size> StringLiteral(char const (&str)[size]){ start=str; this->size=size; } friend ostream& operator<<(ostream& out,StringLiteral const& sl){ out.write(sl.start,sl.size-1); } }ostringstream oss; oss<<StringLiteral("\10\0\0\0\1\3"); oss<<std::string("HELLO").c_str()); oss<<StringLiteral("\10\10\0");