Char-Array definieren



  • [Rewind] schrieb:

    Der Vorschlag mit std::string kam am Anfang als er noch keine Zahlen verschicken wollte. Da er aber die Zahlen und die Strinliterale separat auswerten wird, kann man überlegen, ob man nicht zwei Datenpakete schickt. Wenn der Befehl als Ganzes ausgewertet wird, dann ist string bestens geeignet.

    Er wollte schon im ersten Post Zahlen schicken.



  • _matze schrieb:

    zuckerlie schrieb:

    if (send(s, instr.c_str(), 29, 0) < 0)
    

    Probier das mal und achte darauf, dass ein char nur ein Zeichen ist und nicht '25'.

    Wenn überhaupt, sollte man std::string::size() verwenden und nicht selber zählen. size() verzählt sich nicht. Aber eine 0 in std::string unterzubringen bzw. danach noch was zu verwertendes, ist gar nicht so einfach. Ich denke, std::string ist hier nicht angebracht. Eher ein old-style Array oder std::vector<char>.

    ist aber kein problem.

    std::string asd = "\0\0\0\0asd";
    std::cout.write(asd.c_str(), asd.size());
    

    steht auch im standard irgendwo, dass string '\0' beinhalten darf ohne kaputt zu gehen.

    bb



  • unskilled schrieb:

    steht auch im standard irgendwo, dass string '\0' beinhalten darf ohne kaputt zu gehen.

    Echt? Cool. Wie funktioniert denn das? Wird nicht nur ein const char* an den Konstruktor gegeben? Bin tatsächlich etwas überrascht gerade. 🙂



  • cooky451 schrieb:

    unskilled schrieb:

    steht auch im standard irgendwo, dass string '\0' beinhalten darf ohne kaputt zu gehen.

    Echt? Cool. Wie funktioniert denn das? Wird nicht nur ein const char* an den Konstruktor gegeben? Bin tatsächlich etwas überrascht gerade. 🙂

    stimmt, ist natürlich der falsche ctor und somit hab ich doch müll geschrieben - sry.
    beinhalten darf der string '\0' zwar natürlich aber wenn man die zeichen nicht einzeln per push_back hinzufügt, muss man natürlich den ctor aufrufen:
    string(const char* str, size_type length)
    (oder die iterator variante)

    gehen würde z.bsp. folgendes:

    #include <iostream>
    #include <string>
    
    int main()
    {
    	char buf[] = {'\0', '\0', 'A' };
    	std::string str(buf, sizeof(buf)/sizeof(buf[0]));
    
    	std::cout << str << std::endl; //geht, weiß aber nicht, ob das vom standard garantiert ist - spielt hier aber auch keine rolle
    	std::cout.write(str.c_str(), str.size()); //geht auf jeden fall
    
    	std::cin >> buf[0];
    }
    

    ja, diesmal hab ichs extra getestet, bevor ich wieder was falsches erzähl^^

    bb



  • Jo, stimmt, so einfach kann das sein. 🙂



  • Moin und besten Dank für Eure Hilfen!

    char buf[] = "\x00\x00\x19R:SCRW1_H_BAR_Z02.ACT.VAL";
    

    ...ist letzen Endes zielführen. (Das "\" vor dem "R" hat dem Compiler nicht gefallen, deswegen habe ich es noch entfernt.)

    Allerdings habe ich nun zwei neue Probleme:

    1.) Was bei dem langen Befehl funktioniert hat, funktioniert bei dem kurzen Befehl hier leider nicht:

    //char buf[] = "\x00\x00\x02V:";
    
    buf[0] = 0;			
    buf[1] = 0;			
    buf[2] = 2;			
    buf[3] = 'V';		
    buf[4] = ':';
    

    Sind die beiden Varianten denn vom Inhalt her gleich, oder habe ich etwas falsch gemacht?

    2.) Ich müsste buf[] in meinem Programm mehrfach mit anderem Inhalt füllen. Wenn ich es einmal verwendet habe und dann später im Programm noch "umdefinieren" möchte, sagt mir der Compiler, dass das nicht geht. Geht´s aber vielleicht doch? 😉 Oder muss ich mir für jeden Befehl eine neue Variable definieren?

    Besten Dank und viele Grüße
    Tobsen



  • tobsenmh schrieb:

    2.) Ich müsste buf[] in meinem Programm mehrfach mit anderem Inhalt füllen. Wenn ich es einmal verwendet habe und dann später im Programm noch "umdefinieren" möchte, sagt mir der Compiler, dass das nicht geht. Geht´s aber vielleicht doch? 😉 Oder muss ich mir für jeden Befehl eine neue Variable definieren?

    geht nicht.
    was aber geht:

    std::string gimme_x()
    {
      const char[] value = { '\0', 'A', 'S', 'D' };
    
      return std::string(value, sizeof(value)/sizeof(*value));
    }
    
    std::string gimme_y()
    {
      const char[] value = { '\0', 'Q', 'W', 'E' };
    
      return std::string(value, sizeof(value)/sizeof(*value));
    }
    
    int main()
    {
      winapi_fct_1(gimme_x().c_str(), gimme_x().size());
      winapi_fct_1(gimme_y().c_str(), gimme_y().size());
    }
    

    bb



  • tobsenmh schrieb:

    Sind die beiden Varianten denn vom Inhalt her gleich, oder habe ich etwas falsch gemacht?

    Du musst schon "\x02" statt "\x19" schreiben.

    tobsenmh schrieb:

    2.) Ich müsste buf[] in meinem Programm mehrfach mit anderem Inhalt füllen. Wenn ich es einmal verwendet habe und dann später im Programm noch "umdefinieren" möchte, sagt mir der Compiler, dass das nicht geht. Geht´s aber vielleicht doch? 😉 Oder muss ich mir für jeden Befehl eine neue Variable definieren?

    Du kannst buf mehrfach füllen, z.B. mit strcpy/memcpy, aber das lohnt nicht, da du dann auf die Größe etc. achten musst. Nimm einfach neue Variablen.

    Edit: @unskilled
    Na ja, ich finde hier liefert std::string irgendwie überhaupt keinen Vorteil.. es wird eher komplizierter, unsicherer und langsamer. Warum nicht gleich:

    int main()
    {
      const char msg1[] = "...";
      send(sock, msg1, sizeof(msg1), buf);
      const char msg1[] = ",,,";
      send(sock, msg2, sizeof(msg2), buf);
    }
    


  • So, ich will Euch dann noch kurz über die finale Lösung berichten: Aus irgendwelchen Gründen kommuniziert die Maschine nur dann vernünftig (!) mit mir, wenn ich bei send und recv mit dem array buf arbeite... Warum? Ich weiß es nicht! Auf jeden Fall kopiere ich mir jetzt halt vor jeder Anfrage meinen spezifischen Inhalt in mein buf-Array:

    char z01_act[]="\0\0\x19R:SCRW1_H_BAR_Z01.ACT.VAL";
    memcpy (buf, z01_act, sizeof(z01_act));
    
       if (send(s, buf, 28, 0) < 0)
    

    Ebenso muss ich mit der exakten Längenangabe (hier: "28") beim Funktionsaufruf arbeiten, da ein sizeof() ebenfalls zu Kommunikationsproblemen führt.

    Besten Dank aber nochmal für Eure Anregungen!
    Viele Grüße
    Tobsen



  • tobsenmh schrieb:

    So, ich will Euch dann noch kurz über die finale Lösung berichten: Aus irgendwelchen Gründen kommuniziert die Maschine nur dann vernünftig (!) mit mir, wenn ich bei send und recv mit dem array buf arbeite... Warum? Ich weiß es nicht! Auf jeden Fall kopiere ich mir jetzt halt vor jeder Anfrage meinen spezifischen Inhalt in mein buf-Array:

    char z01_act[]="\0\0\x19R:SCRW1_H_BAR_Z01.ACT.VAL";
    memcpy (buf, z01_act, sizeof(z01_act));
     
       if (send(s, buf, 28, 0) < 0)
    

    Zeig doch noch mal, wie du buf jetzt deklarierst. Irgendwo muss ja ein Unterschied zwischen char-Array 1 und char-Array 2 sein. 😉

    tobsenmh schrieb:

    Ebenso muss ich mit der exakten Längenangabe (hier: "28") beim Funktionsaufruf arbeiten, da ein sizeof() ebenfalls zu Kommunikationsproblemen führt.

    sizeof funktioniert mit Arrays, aber nicht mit Zeigern auf Arrays! Dann kriegst du nämlich nur die Größe des Zeigers (z.B. 4 Bytes). Sowas kann dir aus Versehen passieren, wenn du ein Array an eine Funktion übergibst, dann hast du in der Funktion nämlich nur einen Zeiger (Stichwort array-to-pointer-decay). Oder natürlich, wenn du direkt einen Zeiger deklarierst und ihm dann dynamisch reservierten Speicher (new[]/malloc) zuweist. Dann funktioniert sizeof nicht so, wie du es gerne hättest.



  • _matze schrieb:

    Zeig doch noch mal, wie du buf jetzt deklarierst. Irgendwo muss ja ein Unterschied zwischen char-Array 1 und char-Array 2 sein. 😉

    So:

    char buf[1024];
    


  • Hm, und wenn du z01_act mit korrekter Längenangabe übergibst (also nicht per sizeof), dann hast du das Problem? Ich sehe da gerade keinen Unterschied. Du hast also statt

    char z01_act[]="\0\0\x19R:SCRW1_H_BAR_Z01.ACT.VAL";
    memcpy (buf, z01_act, sizeof(z01_act));
    
       if (send(s, buf, 28, 0) < 0)
    

    auch das hier

    char z01_act[]="\0\0\x19R:SCRW1_H_BAR_Z01.ACT.VAL";
    
       if (send(s, z01_act, 28, 0) < 0)
    

    versucht, und genau so klappt es nicht?



  • Ja _matze, die "Alternative" führt zu Problemen in der Kommunikation mit der Maschine. Ich verstehe es ehrlich gesagt auch nicht, aber mein Problem ist (vorerst) gelöst, die Kommunikation steht, basiert auf einem halbwegs übersichtlichen Code und ich danke Euch für Eure Hilfe! :xmas1:


Anmelden zum Antworten