Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Array of char in einen String umwandeln
Serge - Do 22.03.07 11:46
Titel: Array of char in einen String umwandeln
Hallo erst mal an allen Helfer und Forumbesucher!
Ich habe ein Problem mit dem Array of char.
und zwar ich lese von der serielle Schnittstelle einen nullterminierten String
in ein Array of Char, aber ich brauche einen String, um ihn dann im EditFeld
anzuzeigen oder in eine Zahl umzuwandeln.
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:
| const TempBufSize = 2048; var InQue, OutQue : longint; {$IFDEF DELPHI4UP} ToRead, HasRead : cardinal; e : cardinal; i : cardinal; {$ELSE} ToRead, HasRead : longint; e : longint; i : integer; {$ENDIF} Buf : array[0..20] of char; begin ToRead:=InQue; if (ToRead>TempBufSize) then ToRead:=TempBufSize; ReadFile(Form1.Cid,Buf,ToRead,HasRead,@Overlapped); end; Buf[HasRead]:=#0; Form1.MemoRxD.Lines.Text:=Form1.MemoRxD.Lines.Text+Buf; i:=i+HasRead; Form1.LabelRxD.Caption:=IntToStr(i); end; end; |
Ich versuchte die Daten in String auszulezen
so:
Empfangstr: String [12]; // 11 stellige Zahl + <lf><cr> Also noch zwei stellen ??
ReadFile(Form1.Cid,EmpfangStr,12,HasRead,@Overlapped);
aber das hat auch nicht ganz geklappt, etste Vorzeichen wurde einfach ausgelassen.
bestimmt mache ich was falsch, aber der Code für die Serielle ist nicht meins und in Delphi bin ich auch ein Anfänger..kann mir vielleicht jemand irgendwie weiter helfen??
wulfskin - Do 22.03.07 11:53
Delphi-Quelltext
1:
| ReadFile(Form1.Cid,EmpfangStr[1],12,HasRead,@Overlapped); |
Oder du benutzt die Funktion
StrPCopy,
Move o.ä die einen Array in einen String kopiert!
Edit: Du bist sicher, dass die Zahl nicht binär ankommt?
Gruß Hape!
Serge - Do 22.03.07 12:14
das Gerät wandelt alles in ASCII Code um
ich habe ein Programm unter Excel, das serielle abfragt, da bekomme ich das
Ausgelesenes in sauberen Strings. Aber um das programm zum Laufen zu bringen, verwende ich eine fertige DLL,
mit fertigen Funktionen für die serielle Schnittstelle. Das macht vieles leichter.
aber in VBA habe ich leider keine Möglichkeit, einigen Abfrage-Schleifen in treads zu packen.
Serge - Do 22.03.07 12:44
Bei der Bearbeitung von nullterminierten Strings ist häufig der Einsatz von Zeigern erforderlich (siehe Zeiger und Zeigertypen). String-Konstanten sind zuweisungskompatibel zu den Typen PChar und PWideChar, die Zeiger auf nullterminierte Arrays mit Char- und WideChar-Werten darstellen. Im folgenden Beispiel zeigt P auf einen Speicherbereich, der eine nullterminierte Kopie von Hello world! enthält:
Delphi-Quelltext
1: 2: 3: 4:
| var P: PChar;
... P := 'Hello world!'; |
Die folgenden Programmzeilen sind mit den obigen Zeilen identisch:
Delphi-Quelltext
1: 2: 3: 4: 5:
| const TempString: array[0..12] of Char = 'Hello world!'#0;
var P: PChar; ... P := @TempString; |
wie kann man das irgendwie weiter benutzen??
Moderiert von
Christian S.: Delphi-Tags hinzugefügt
BenBE - Do 22.03.07 14:01
Wenn Du direkt den String schon in einem Array of Char hast, kannst Du ab Delphi 7 einfach dieses Array (ohne angabe eines Startindex) an den String zuweisen ...
Bei vorhergehenden Delphi-Versionen empfiehlt sich die Nutzung der Funktion StrPas, der Du einen Zeiger auf das erste Zeichen übergibst.
Also z.B. StringVariable := StrPas(@DeinArray[0]);
Ansonsten wie die anderen das bereits beschrieben haben ...
Serge - Do 22.03.07 14:37
Danke BenBE!!!
das geht:))))
gestatten sie mir noch eine frage...
Warum im Memofeld :
Delphi-Quelltext
1:
| Form1.MemoRxD.Lines.Text:=Form1.MemoRxD.Lines.Text+empfangstr; |
gibtes dies Form1.MemoRxD.Lines.Text+empfangstr?? was soll hier dieses
plus Zaichen?
und warum sehe ich in Form1.Edit1.Text:=trim(empfangstr); nur letzte 3 Zeichen??
In Memofeld steht -002191.500 in Editfeld nur 500
Wie bekomme ich eine Laufende Anzeige im Editfeld???
z.B jede sekunde wird ein Wert von der serielle ausgelesen und ans Editfeld
weitergeben.
BenBE - Do 22.03.07 14:44
Das Plus bei 2 Strings bedeutet String-Konkatenation (Zusammensetzen der beiden Operanden).
Warum er bei Trim nur die letzten 3 Zeichen zurückgibt wundert mich ein wenig. Dazu müsste man aber ggf. einmal mit dem Debugger im Einzelschritt sich die Variablen-Inhalte anschauen.
Ggf. einfach mal kurz die aktuelle Source-Version posten ...
Serge - Do 22.03.07 14:59
ich entwickle mit Delphi 6,
ohne trim ist das selber..steht um zwei Striche mehr
Delphi-Quelltext
1:
| Form1.MemoRxD.Lines.Text:=Form1.MemoRxD.Lines.Text+empfangstr; |
da wird alles richtig angezeigt
Delphi-Quelltext
1:
| Form1.Edit1.Text:=trim(empfangstr); |
da nur die letzten 3 Zeichen..mit trim hat es nicht zu tun...
wenn so ..Form1.Edit1.Text:=Form1.MemoRxD.Lines.Text
wird alles richtig angezeigt, aber in einer Schleife etwa so:
-002191.500-002191.500-002191.500-002191.500
Form1.Label1.Caption:=Form1.MemoRxD.Lines.Text
Wird so angezeigt:
-002191.500
-002191.500
-002191.500
-002191.500
Was ich brauche eine laufenbde anzeige,
wo die letzten Zahl sich um eins ändert.
Die daten kommen wie gesagt , von der serielle Schnittstelle
Serge - Do 22.03.07 15:57
Delphi-Quelltext
1: 2: 3: 4:
| Form1.Edit1.Text:=Form1.Edit1.Text+trim(empfangstr);
Form1.Label3.Caption:=Form1.Label3.Caption+trim(empfangstr); |
Also so geht es auch...schon wider dieses Plus-Zeichen!!!
Aber immer noch speichert das Editfeld letzter Eintrag
und schreibt alles in einer Zeile.
Aber es soll viel einfacher sein:
Edit1.Text:=StringVariable; !!!!!!!!
Warum geht es bei mir nicht??
Abfrage der serielle ist in einem Tread eingepackt.
Ist das wo möglich der grund, für dieses verhalten???
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: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, ComCtrls, DlgCom, Serial;
type TSerThread = class(TThread) constructor Create; procedure Execute; override; end; TForm1 = class(TForm) StatusBar1: TStatusBar; ButtonSetup: TButton; ButtonOpen: TButton; ButtonClose: TButton; ButtonExit: TButton; ButtonSendText: TButton; MemoTxD: TMemo; MemoRxD: TMemo; LabelTxD: TLabel; Label1: TLabel; LabelRxD: TLabel; Label2: TLabel; Timer1: TTimer; Button1: TButton; Edit1: TEdit; Label3: TLabel; procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure ButtonSetupClick(Sender: TObject); procedure ButtonOpenClick(Sender: TObject); procedure ButtonCloseClick(Sender: TObject); procedure ButtonExitClick(Sender: TObject); procedure MemoTxDKeyPress(Sender: TObject; var Key: Char);
procedure ButtonSendTextClick(Sender: TObject); procedure Button1Click(Sender: TObject); procedure NotifyEvent(Sender: Tobject);
public IsOpened, IsClosing : boolean; SerThread : TSerThread;
Cid : THandle; MyTimer1:TTimer; end;
var Form1: TForm1; MyTimer1:TTimer;
implementation
{$R *.DFM}
constructor TSerThread.Create; begin inherited Create(false); FreeOnTerminate:=true; end;
procedure TSerThread.Execute; const TempBufSize = 2048; var InQue, OutQue : longint; {$IFDEF DELPHI4UP} ToRead, HasRead : cardinal; e : cardinal; i : cardinal; {$ELSE} ToRead, HasRead : longint; e : longint; i : integer; {$ENDIF} Buf : array[0..32] of char; empfangstr: string [32]; len:dword; j:integer; begin i:=0; while (not Terminated) do begin if WaitCommEvent(Form1.Cid,e,nil) then begin DataInBuffer(Form1.Cid,InQue,OutQue); Form1.LabelTxD.Caption:=IntToStr(OutQue); if InQue>0 then begin ToRead:=InQue; if (ToRead>TempBufSize) then ToRead:=TempBufSize; ReadFile(Form1.Cid,buf,ToRead,HasRead,@Overlapped);
Buf[HasRead]:=#0; empfangstr := StrPas(@buf[0]); Form1.MemoRxD.Lines.Text:=Form1.MemoRxD.Lines.Text+empfangstr;
Form1.Edit1.Text:=trim(empfangstr); Form1.Label3.Caption:=trim(empfangstr); empfangstr:=''; i:=i+HasRead; Form1.LabelRxD.Caption:=IntToStr(i); end; end; end; end;
procedure TForm1.FormCreate(Sender: TObject); begin IsOpened:=false; IsClosing:=false; Cid:=INVALID_HANDLE_VALUE; end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin IsClosing:=true; ButtonCloseClick(Sender); end;
procedure TForm1.ButtonSetupClick(Sender: TObject); begin FormCOMSetup.ShowModal; end;
procedure TForm1.ButtonOpenClick(Sender: TObject); begin if (not IsOpened) then begin Cid:=OpenComm(FormCOMSetup.UsedPort,FormCOMSetup.dcb,FormCOMSetup.BufSizeR,FormCOMSetup.BufSizeT); IsOpened:=Cid<>INVALID_HANDLE_VALUE; if IsOpened then begin SetCommMask(Cid,EV_RXCHAR); SerThread:=TSerThread.Create; StatusBar1.SimpleText:='Schnittstelle ist geöffnet.'; MemoTxD.Enabled:=true; MemoTxD.Clear; MemoRxD.Clear; end else begin MessageBeep(0); StatusBar1.SimpleText:='Schnittstelle konnte nicht geöffnet werden!'; end; end else begin MessageBeep(0); StatusBar1.SimpleText:='Schnittstelle ist bereits geöffnet!'; end; end;
procedure TForm1.ButtonCloseClick(Sender: TObject); begin if IsOpened then begin SerThread.Terminate; SetCommMask(Cid,0); if CloseComm(Cid) then begin IsOpened:=false; MemoTxD.Enabled:=false; StatusBar1.SimpleText:='Schnittstelle wurde geschlossen.'; end else begin MessageBeep(0); StatusBar1.SimpleText:='Schnittstelle konnte nicht geschlossen werden!'; end end else begin if (not IsClosing) then begin MessageBeep(0); StatusBar1.SimpleText:='Schnittstelle ist bereits geschlossen.'; end; end; end;
procedure TForm1.ButtonExitClick(Sender: TObject); begin Close; end;
procedure TForm1.MemoTxDKeyPress(Sender: TObject; var Key: Char); var {$IFDEF DELPHI4UP} w : cardinal; {$ELSE} w : longint; {$ENDIF} begin if IsOpened then WriteFile(Cid,Key,1,w,@Overlapped); end;
procedure TForm1.ButtonSendTextClick(Sender: TObject); begin
MyTimer1 := TTimer.Create(Self);
MyTimer1.Interval := 1000; MyTimer1.Enabled := TRUE; MyTimer1.OnTimer := NotifyEvent;
end;
procedure TForm1.NotifyEvent(Sender: TObject);
const Data : array[0..6] of char = 'dis,g'+chr(13)+chr(10); var {$IFDEF DELPHI4UP} w : cardinal; {$ELSE} w : longint; {$ENDIF} i:integer; begin WriteFile(Cid,Data,sizeof(Data),w,@Overlapped); end;
procedure TForm1.Button1Click(Sender: TObject);
begin MyTimer1.Destroy ; end; end. |
Moderiert von
Tino: Beiträge zusammengefasst
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!