Char-Array definieren
-
Ersteinmal vielen Dank für Eure schnelle Hilfe.
Leider bin ich noch nicht am Ziel.
Ich habe folgende Varianten ausprobiert://std::string instr("0025R:SCRW1_H_BAR_Z01.ACT.MAX"); //strcpy(buf,"0025R:SCRW1_H_BAR_Z01.ACT.MAX"); //char buf[]={'0','0','25','R:SCRW1_H_BAR_Z01.ACT.MAX'}; //char buf[]={'0','0','25','R',':','S','R','C','W','1','_','H','_','B','A','R','_','Z','0','1','.','A','C','T','.','M','A','X'}; buf[0] = 0; buf[1] = 0; buf[2] = 25; buf[3] = 'R'; buf[4] = ':'; buf[5] = 'S'; buf[6] = 'C'; buf[7] = 'R'; buf[8] = 'W'; buf[9] = '1'; buf[10] = '_'; buf[11] = 'H'; buf[12] = '_'; buf[13] = 'B'; buf[14] = 'A'; buf[15] = 'R'; buf[16] = '_'; buf[17] = 'Z'; buf[18] = '0'; buf[19] = '2'; buf[20] = '.'; buf[21] = 'S'; buf[22] = 'E'; buf[23] = 'T'; buf[24] = '.'; buf[25] = 'V'; buf[26] = 'A'; buf[27] = 'L'; // if (send(s, instr.c_str(), 28, 0) < 0) if (send(s, buf, sizeof(buf), 0) < 0)Nur die nicht auskommentierte Variante funktioniert.
Bei den anderen Varianten friert das Programm an der Stelle, an der eigentlich die Antwort empfangen werden soll ein (="leider ohne Erfolg" @ _matze):
if (recv(s, buf, sizeof(buf), 0) < 0)@zuckerlie: Es sind feste Befehle, die ich nur einmal programmieren muss. D.h. zur Not könnte ich mich auch über die o.g. "Mammutzeilen-Lösung" retten, aber zumindest ein klein wenig schön soll das Programm dann doch schon sein...

@_matze:
buf habe ich so deklariert (Vorlage des Maschinenherstellers):char buf[1024];Viele Grüße
Tobsen
-
'25' gibt's nicht, was genau hast du getestet?
Ansonsten:char buf[] = "\0\0\x19R:SCRW1_H_BAR_Z01.ACT.MAX";
-
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'.
-
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'.
Wie soll das denn gehen? '0' != 0
-
char buf[]={'0','0','25','R',':','S','R','C','W','1','_','H','_','B','A','R','_','Z','0','1','.','A','C','T','.','M','A','X'};buf[0] = 0; buf[1] = 0; buf[2] = 25; ...Du erzeugst hier mit den beiden Methoden nicht den gleichen String! 0 ist was ganz anderes als '0'. Du musst scheinbar am Anfang ein paar Steuerzeichen schicken, bevor der eigentliche Datenstring erwartet wird. Wenn dein Programmm mit den alternativen Methoden einfriert, dann vermutlich nur, weil du auf eine Antwort vom Gerät wartest, die einfach nicht kommt, weil du nie einen validen Befehl gesendet hast. Du kannst nicht druckbare Zeichen per Escape-Sequenz in einen String packen. Probier mal so:
char buf[]="\x00\x00\x19\R:SCRW1_H_BAR_Z01.ACT.MAX"; //die ersten Zeichen sind 0,0,25 (dezimal)
-
1. Verwende nicht Konstante, sondern die tatsächliche Länge des Strings, damit da kein Mist eingelesen bzw. nichts abgeschnitten wird.
2. Verwende Konstante zur Überprüfung des Funktionsrückgabewertes. Ein beim Senden aufgetretene Fehler wird mit SOCKET_ERROR signalisiert und, wie du siehst, ist das nicht 0.WinSock2.h schrieb:
#define SOCKET_ERROR (-1)
Also:
std::string instr("0025R:SCRW1_H_BAR_Z01.ACT.MAX"); ... int sendResult = send(s, instr.c_str(), instr.size(), 0); if (sendResult != SOCKET_ERROR) ... else //Fehler in sendResult auswerten!!!Ansonsten weiß ich nicht, warum es bei dir schiefläuft.
Edit: Jetzt ist halt die Frage, was bei dir nach dem if im Code kam: das auszuführende Programm oder eine Fehlerbehandlung. Ich hoffe das Letztere.
-
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>.
-
[Rewind] schrieb:
Ansonsten weiß ich nicht, warum es bei dir schiefläuft.
Lies doch mal die anderen Beiträge. Es liegt an 0!='0'. Er braucht 0, schreibt bei seinem Versuchen in die Stringliterale aber '0' rein.
-
Der Vorschlag mit std::string kam am Anfang als er noch keine Zahlen verschicken wollte. Da er aber die Zahlen und die Stringliterale wahrscheinlich separat auswerten wird, kann man überlegen, ob man nicht zwei Datenpakete schickt. Wenn der Befehl als Ganzes ausgewertet wird, dann ist string bestens geeignet.
-
[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
bufjetzt 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.
sizeoffunktioniert 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 funktioniertsizeofnicht so, wie du es gerne hättest.
-
_matze schrieb:
Zeig doch noch mal, wie du
bufjetzt deklarierst. Irgendwo muss ja ein Unterschied zwischen char-Array 1 und char-Array 2 sein.
So:
char buf[1024];