Autor Beitrag
DesperadoStrike
Hält's aus hier
Beiträge: 14



BeitragVerfasst: So 31.05.09 13:08 
Hallo zusammen, ich weiß von der Sorte gibts 1000 Themen aber ich habe leider keines finden können, welches annähernd auf mein Problem passt. Naja vielleicht bin ich auch nur blind.

Meine Frage lautet wie folgt:

Über einen Netzwerkcode lasse ich mir in regelmäßigen abständen einen String senden der folgendes Schema hat

123@123
2343@231
13@213

usw.

Nun brauche ich die Werte die vor dem @ und die nach dem @ stehen.

Das Problem dabei ist: die Werte sind nicht immer gleich lang. Sie können zwischen 1 - 4 zeichen auf beidenseiten Variieren.

CBleft := copy(res, 1, 3);
CBtop := copy(res, 5, 7);

funktioniert daher nicht richtig.

Könnt ihr mir eine gute lösung zeigen, wie ich es bewerkstelligen kann, die Stellen vor dem @- Trennzeichen zu zählen und anschließend zu kopieren?

Würde mich über Hilfe freuen :)
Jann1k
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 866
Erhaltene Danke: 43

Win 7
TurboDelphi, Visual Studio 2010
BeitragVerfasst: So 31.05.09 13:13 
Schau dir mal die Funktion pos an, mit ihr kannst du herausfinden an welcher Stelle im String das @ vorkommt und dein copy dementsprechend aufrufen.
jakobwenzel
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1889
Erhaltene Danke: 1

XP home, ubuntu
BDS 2006 Prof
BeitragVerfasst: So 31.05.09 13:13 
Pos und length sind deine Freunde.

_________________
I thought what I'd do was, I'd pretend I was one of those deaf-mutes.
ffgorcky
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 573

WIN XP/2000 & 7Prof (Familie:Win95,Win98)

BeitragVerfasst: So 31.05.09 13:46 
Du könntest das ganze doch auch mit Split(zuZerteilenderText,'@',MemoGesplittet.Lines); machen,
wie ich das jetzt gerade im Post 55713 entdeckt habe.
DesperadoStrike Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: So 31.05.09 13:55 
Ich poste einfach mal den entsprechenden Codefetzen


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
procedure TForm1.PingTimer(Sender: TObject);
var CBLeft, CBTop : integer;
    gesendet : word;

begin
CBLeft := checkbox1.Left;
CBTop  := checkbox1.Top;

ServerSocket1.Socket.Connections[0].SendText(InttoStr(CBTop)+InttoStr(CBLeft));
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
 var res: ansistring;
     CBleft, CBtop : string;
      empfangen : word;
begin
SetLength(res, Socket.ReceiveBuf(Pointer(nil)^, -1));
SetLength(res, Socket.ReceiveBuf(Pointer(res)^, Length(res)));

Memo1.Lines.Add(res);

CBTop := copy(res, 12);
CBLeft  := copy(res, 35);

checkbox2.Top := StrtoInt(CBtop);
checkbox2.Left := StrtoInt(CBleft);
end;
end.



eigentlich sollte der code so aussehen:
(InttoStr(CBTop)+'@'+InttoStr(CBLeft));

aber irgentwie bringt er mir dann auf einer Seite immer den ""88-"Ist kein gültiger Integer Wert" Fehler. Warum weiß ich nicht genau.

Der Netzwerkcode funktioniert zwar so wie er momentan ist,

Bsp: Empfange => 88232

CBTop := copy(res, 1, 2);
CBLeft := copy(res, 3, 5);

=> 88
=> 232

allerdings nur solange ich mich in dem 2 Stellen bereich bewege.

Moderiert von user profile iconGausi: Quote- durch Delphi-Tags ersetzt
ffgorcky
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 573

WIN XP/2000 & 7Prof (Familie:Win95,Win98)

BeitragVerfasst: So 31.05.09 14:22 
Naja, dass ein Minus nicht hinter eine Zahl gehört (also so wie bei Deiner Fehlermeldung 88-) ist aber schon klar - oder?
Und wie Du genau bestimmen kannst, in welcher Zeile der Fehler entsteht weißt Du hoffenlich auch - oder?
- Also ich meine jetzt, wie Du zeilenweise debuggen kannst.
DesperadoStrike Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: So 31.05.09 14:35 
ürsprünglich war das - ja auch ein @ aber das wollte nicht so ganz funktionieren deshalb habe ich ein anderes zeichen ausprobiert
ffgorcky
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 573

WIN XP/2000 & 7Prof (Familie:Win95,Win98)

BeitragVerfasst: So 31.05.09 15:21 
Könntest Du denn den zu sendenen Code (also auf der ServerSeite) immer gleich lang machen?
- Sprich: den zu sendenden Wert immer mit Nullen auffüllen?
Dann könntest Du zum Beispiel bei (D)einer Standardlänge von 4 Zeichen den gesendeten Code 000230040700002
Doch ohne weiteres in
1.Teil:0023
2.Teil:0407
3.Teil:0002
aufteilen.
Das wäre auch eine recht gängige Lösung!


Zuletzt bearbeitet von ffgorcky am So 31.05.09 15:28, insgesamt 1-mal bearbeitet
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19341
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 31.05.09 15:23 
user profile iconDesperadoStrike hat folgendes geschrieben Zum zitierten Posting springen:
ürsprünglich war das - ja auch ein @ aber das wollte nicht so ganz funktionieren deshalb habe ich ein anderes zeichen ausprobiert
Das hat mit dem Zeichen doch nichts zu tun. Dem Fehler nach zu urteilen musst du von der Länge des zu kopierenden Teils bei dem entsprechenden Quelltext nur eins abziehen, weil er das Zeichen mit kopiert.
Lake
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 78


D6 prof., Delphi 10.2 Tokyo
BeitragVerfasst: So 31.05.09 15:28 
Vielleicht hilft Dir das.
Hier ist es egal wo das "@" steht.

ausblenden Delphi-Quelltext
1:
2:
3:
  s := '12@34567';
  s1 := LeftStr(s,(pos('@',s)-1));
  s2 := RightStr(s,(length(s)-(pos('@',s))));

_________________
Gruss Lake
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19341
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 31.05.09 15:32 
Das sieht korrekt aus. :nixweiss:
Genauso sollte das funktionieren, dann brauchst du die Unit StrUtils nicht:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
  s := '12@34567';
  TempInt := Pos('@', s);
  s1 := Copy(s, 1, TempInt - 1);
  s2 := Copy(s, TempInt + 1, MaxInt);
DesperadoStrike Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: So 31.05.09 16:38 
Super das hat mein problem gelöst danke dir :-D


edit:

es hat sich ein neues Problem ergeben:

Wenn ich die Sendezeiten auf kleine Werte ~150+ setze, dann kommen die Daten zu schnell an, und ich fliege aus dem Programm mit der begründung 1233132@313@341231 ist kein gültiger Integerwert. Wenn ich den Timeout auf 500-1000 setze, dann ist die übertragung nicht flüssig.

Kann man das irgentwie machen? Z.b. das ein neues Paket erst dann geschickt wird, wenn der ZielPC eine bestätigung gesendet hat, das das paket ankam.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19341
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 31.05.09 17:00 
Also erstens benutze einmal TryStrToInt, um den Fehler abzufangen. Und dann: Wieviele Integers verkettest du da eigentlich, bist du sicher, dass du das wirklich so umsetzen willst? Ich meine, wäre es nicht sinnvoller ein richtiges Protokoll zu verwenden?

Ich vermute, dass dir nicht klar ist, dass die gesendeten Daten nicht notwendigerweise auch in den Paketen so einzeln wieder ankommen müssen wie du sie geschickt hast...

Mehr dazu findest du in dieser Tutorialserie:
www.delphi-library.de/topic_54269.html
DesperadoStrike Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: So 31.05.09 17:07 
Naja genau genommen ist das eigentlich nur eine kleine Spielerei die ich zurzeit mache, weil ich mal testen will, in wie weit ich in der Lage bin, Netzwerkcode zu programmieren.

Das ganze Funktioniert nach einem einfachen Prinzip:

Ich benutze die Server & Client Sockets, 2 Checkboxen und 4 Buttons.

Mit den 4 boxen kann Client die Checkbox 1 steuern, der Server steuert nach dem gleichen Prinzip die Checkbox 2.

Am anfang habe ich die Daten mittels Chat befehle abgeglichen, sprich => Client drückt "Links Button" => Chat Command "links" wird zum Server gesendet => wenn Server das Wort empfängt => bewege die Checkbox.


Mittlerweile mache ich es mittels einen Timer, der so Programmiert ist, das er jede Sekunde die Position von Left / Top zum Server / Client schickt. Das ganze sieht dann z.b. so aus

88@230.

Durch den Filter code von euch lasse ich entsprechend die Daten auswerten. Dies Funktioniert soweit auch ganz gut, aber durch den hohen Interval ist das ganze sehr ruckelig. Kleinere Intervale sorgen dafür, das zu viele Daten in zu kurzer Zeit verschickt werden.

Einen wirklichen sinn hat das Programm nicht, es ist mehr ein Netzwerktest.

Leider finde ich keine guten Netzwerk tutorials für diese Art, also habe ich mich selber mit einer eigenen Idee durchgewurschtelt. Ob der Code nun gut oder schlecht läuft ist in erster Linie erstmal egal, da es nur ein fun Projekt ist.


Allerdings bin ich für bessere Ideen immer offen. Bin noch anfänger daher verstehe ich so "komplexe" Tutorials nicht.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19341
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 31.05.09 17:12 
In dem verlinkten Tutorial kommt u.a. ein Binärtutorial vor, was wohl eher de, entspricht was du vor hast. Aber auch das direkt verlinkte sollte für deinen Zweck schon richtig sein.

Und auf diese Art und Weise sollte der Effekt, den du jetzt beobachtest, nicht mehr auftreten.
DesperadoStrike Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: So 31.05.09 17:35 
Zitat:
Leider funktioniert das nur deshalb, weil die Datenrate3 klein genug ist, um das Ereignissystem
von Windows nicht zu überfordern, das nicht sehr schnell ist. Würden sehr viel mehr Daten auf
einmal gesendet, könnten in der Zeit, bis die Ereignisverarbeitung in unserem Programm beginnt,
bereits weitere Daten eingetroffen sein! Dann würde .ReceiveText mehr liefern, als
von den einzelnen .SendText()-Aufrufen gesendet wurde.



Ich glaube vor diesem Problem stehe ich gerade :-)
Raid
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 16

Win XP Home, Win XP Prof., Win Vista
Delphi 2009 Arch.
BeitragVerfasst: Mo 01.06.09 05:04 
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
type
  TMeineZweiStrings = array [0..1of string;

function MeineFunktion(const MeinParameter: string): TMeineZweiStrings;
var
  MeineStringList: TStringList;
begin
  MeineStringList := TStringList.Create;
  try
    MeineStringList.StrictDelimiter := true;
    MeineStringList.Delimiter := '@';
    MeineStringList.DelimitedText := MeinParameter;

    Result[0] := MeineStringList[0];
    Result[1] := MeineStringList[1];
  finally
    MeineStringList.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  MeineZweiStrings: TMeineZweiStrings;
  MeinStringEins,
  MeinStringZwei: string;
begin
  MeineZweiStrings := MeineFunktion('1234@5678');
  MeinStringEins := MeineZweiStrings[0];
  MeinStringZwei := MeineZweiStrings[1];

  ShowMessageFmt('Mein String 1: %s' + sLineBreak + 'Mein String 2: %s', [MeinStringEins, MeinStringZwei]);
end;
So kommt ihr 100% an die einzelnen Nummern ^^