字符串连接不起作用
String concatenation doesn't work
我创建了一个简单的 class 来存储从串行端口接收的数据,并根据特定条件拆分它。我意识到它没有正常工作,所以我一步一步地重新编码以查看问题所在。我发现这是一个字符串连接。下面是class的代码。失败的行是 buffer = buffer + tail;
unit InBuffer;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils;
type
TInBuffer = class
private
buffer: String;
messages: TStrings;
public
constructor Create;
destructor Destroy;
procedure Add(tail: string);
function getBuffer: String;
function getLast: String;
function DataAvailable: boolean;
end;
implementation
constructor TInBuffer.Create;
begin
buffer := '';
messages := TStringList.Create;
end;
destructor TInBuffer.Destroy;
begin
messages.Free;
inherited Destroy;
end;
procedure TInBuffer.Add(tail: string);
begin
buffer := buffer + tail;
end;
function TInBuffer.GetBuffer: String;
begin
Result := buffer;
end;
function TInBuffer.GetLast: String;
begin
if DataAvailable then
begin
Result := messages[0];
messages.Delete(0);
end;
end;
function TInBuffer.DataAvailable: boolean;
begin
Result := messages.Count > 0;
end;
end.
我使用 SdpoSerial 进行交流。在 OnRxData 事件中我有这段代码。
procedure TfrmMain.serOnRxData(Sender: TObject);
var
msg: string;
begin
msg := ser.ReadData;
buff.Add(msg);
log('Stored buffer: ' + buff.getBuffer);
log('Receive trace: ' + msg);
end;
在日志中,我在 "Receive trace" 中看到了正确的数据,但是 "Stored buffer" 中的行始终相同(通信中收到的第一条消息)。我试过使用 Copy
或 Concat
之类的函数来构建缓冲区,但没有任何变化。
我可能做错了什么?
谢谢。
编辑:
按照 Abelisto 的建议,我将这段代码放在按钮的 onClick 事件中
buff.Add('111');
buff.Add('222');
ShowMessage(buff.getBuffer);
显示的消息是正确的。因此,传递来自串行端口的数据存在一些问题。它在日志中正确显示,但不在缓冲区中。有什么想法吗?
虽然 RS232 等外部设备可以 post 到端口,但您必须为此做好准备。在我们的例子中,设备 post NULL 字符打破了 C 语言编写的字符串 OS。 Pascal 字符串可以处理它但不能处理 OS wigets。但是,我对像应用程序这样的控制台感到困惑,它可以很好地处理 NULL 字符。所以要小心。
我创建了一个简单的 class 来存储从串行端口接收的数据,并根据特定条件拆分它。我意识到它没有正常工作,所以我一步一步地重新编码以查看问题所在。我发现这是一个字符串连接。下面是class的代码。失败的行是 buffer = buffer + tail;
unit InBuffer;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils;
type
TInBuffer = class
private
buffer: String;
messages: TStrings;
public
constructor Create;
destructor Destroy;
procedure Add(tail: string);
function getBuffer: String;
function getLast: String;
function DataAvailable: boolean;
end;
implementation
constructor TInBuffer.Create;
begin
buffer := '';
messages := TStringList.Create;
end;
destructor TInBuffer.Destroy;
begin
messages.Free;
inherited Destroy;
end;
procedure TInBuffer.Add(tail: string);
begin
buffer := buffer + tail;
end;
function TInBuffer.GetBuffer: String;
begin
Result := buffer;
end;
function TInBuffer.GetLast: String;
begin
if DataAvailable then
begin
Result := messages[0];
messages.Delete(0);
end;
end;
function TInBuffer.DataAvailable: boolean;
begin
Result := messages.Count > 0;
end;
end.
我使用 SdpoSerial 进行交流。在 OnRxData 事件中我有这段代码。
procedure TfrmMain.serOnRxData(Sender: TObject);
var
msg: string;
begin
msg := ser.ReadData;
buff.Add(msg);
log('Stored buffer: ' + buff.getBuffer);
log('Receive trace: ' + msg);
end;
在日志中,我在 "Receive trace" 中看到了正确的数据,但是 "Stored buffer" 中的行始终相同(通信中收到的第一条消息)。我试过使用 Copy
或 Concat
之类的函数来构建缓冲区,但没有任何变化。
我可能做错了什么?
谢谢。
编辑: 按照 Abelisto 的建议,我将这段代码放在按钮的 onClick 事件中
buff.Add('111');
buff.Add('222');
ShowMessage(buff.getBuffer);
显示的消息是正确的。因此,传递来自串行端口的数据存在一些问题。它在日志中正确显示,但不在缓冲区中。有什么想法吗?
虽然 RS232 等外部设备可以 post 到端口,但您必须为此做好准备。在我们的例子中,设备 post NULL 字符打破了 C 语言编写的字符串 OS。 Pascal 字符串可以处理它但不能处理 OS wigets。但是,我对像应用程序这样的控制台感到困惑,它可以很好地处理 NULL 字符。所以要小心。