Delphi 比如StrTok()或Sscanf()?
因此,我通过串行端口从ModBos读取数据,得到如下读数:Delphi 比如StrTok()或Sscanf()?,delphi,modbus,Delphi,Modbus,因此,我通过串行端口从ModBos读取数据,得到如下读数:'+0020.8+0022.8-00.046-00.002-00.005-001.99+00.000+00.003' 基本上,将始终有8个浮点读数,前面有加号或减号,尽管它们可能具有不同的字符长度 从float数组(或string数组或TSringList)中获取值的最有效方法是什么 我不确定,但这可能是时间关键,因此效率可能远远超过优雅。您可以下载并使用移植到Delphi的VC++。我会这样做: type TFloatArray =
'+0020.8+0022.8-00.046-00.002-00.005-001.99+00.000+00.003'代码>
基本上,将始终有8个浮点读数,前面有加号或减号,尽管它们可能具有不同的字符长度
从float数组(或string数组或TSringList)中获取值的最有效方法是什么
我不确定,但这可能是时间关键,因此效率可能远远超过优雅。您可以下载并使用移植到Delphi的VC++。我会这样做:
type
TFloatArray = array[0..7] of Double;
procedure ParseFloats(const aFloatStr: string;
var aFloatArray: TFloatArray);
var
lPos: Integer;
lNextPos: Integer;
lPosPositive: Integer;
lPosNegative: Integer;
i: Integer;
lFormatSettings: TFormatSettings;
begin
//do not forget formatsettings, or you will get problems with regional settings
lFormatSettings.DecimalSeparator := '.';
lFormatSettings.ThousandSeparator := ',';
lPos := 1;
for i := 0 to High(aFloatArray) do
begin
lPosPositive := PosEx('+', aFloatStr, lPos + 1);
lPosNegative := PosEx('-', aFloatStr, lPos + 1);
if lPosPositive = 0 then
lNextPos := lPosNegative
else if lPosNegative = 0 then
lNextPos := lPosPositive
else
lNextPos := Min(lPosPositive, lPosNegative);
if lNextPos = 0 then
lNextPos := Length(aFloatStr) + 1;
aFloatArray[i] := StrToFloat(Copy(aFloatStr, lPos, lNextPos - lPos), lFormatSettings);
lPos := lNextPos;
end;
end;
//call like this
var
lFloats: TFloatArray;
begin
ParseFloats('+0020.8+0022.8-00.046-00.002-00.005-001.99+00.000+00.003', lFloats);
end;
因为总是有8个浮点值,一个8倍的固定数组就足够了。我将字符串操作限制在最低限度,每个浮点值只复制一次字符串。重要的是TFormatSetting,否则在十进制分隔符不是点的系统(如我的系统)上会出现错误
这里没有异常处理,我希望字符串包含8个浮点值,不多不少。您可以使用该类来解析字符串
检查此示例应用程序
program ParserDemo;
{$APPTYPE CONSOLE}
uses
Classes,
SysUtils;
procedure ProcessModBosOutPut(OutPut : string);
var
StringStream : TStringStream;
Parser : TParser;
dValue : Double;
sValue : string;
FormatSettings: TFormatSettings;
begin
FormatSettings.DecimalSeparator :='.';
FormatSettings.ThousandSeparator:=',';
//transform the output string to fit with the TParser logic
OutPut:=StringReplace(OutPut,'+',' ',[rfReplaceAll]); //replace '+' sign with a space
OutPut:=StringReplace(OutPut,'-',' -',[rfReplaceAll]); //insert a empty space after of a '-' sign
StringStream:=TStringStream.Create(OutPut);
Parser:=TParser.Create(StringStream);
try
while Parser.Token <> toEOF do
begin
sValue:=Parser.TokenString; //get the string
dValue:=StrToFloat(sValue,FormatSettings); //convert the string
//do something with the float value
Writeln(FloatToStr(dValue));
Parser.NextToken;
end;
finally
Parser.Free;
StringStream.Free;
end;
end;
begin
try
ProcessModBosOutPut('+0020.8+0022.8-00.046-00.002-00.005-001.99+00.000+00.003');
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
Readln;
end.
programmparserdemo;
{$APPTYPE控制台}
使用
班级,
SysUtils;
过程ProcessModBosOutPut(输出:字符串);
变量
StringStream:TStringStream;
解析器:TParser;
d值:双倍;
sValue:字符串;
格式设置:t格式设置;
开始
FormatSettings.DecimalSeparator:='.';
FormatSettings.MilliandSeparator:=',';
//转换输出字符串以适应TParser逻辑
输出:=StringReplace(输出“+”,“[rfReplaceAll])//将“+”符号替换为空格
输出:=StringReplace(输出'-','-',[rfReplaceAll])//在“-”号后面插入空格
StringStream:=TStringStream.Create(输出);
解析器:=TParser.Create(StringStream);
尝试
while Parser.toedo的标记
开始
sValue:=Parser.TokenString//获取字符串
dValue:=StrToFloat(sValue,FormatSettings)//转换字符串
//用浮点值做些什么
Writeln(FloatToStr(dValue));
Parser.NextToken;
结束;
最后
解析器。免费;
StringStream.免费;
结束;
结束;
开始
尝试
ProcessModBos输出('+0020.8+0022.8-00.046-00.002-00.005-001.99+00.000+00.003');
除了
关于E:Exception-do
Writeln(E.Classname,“:”,E.Message);
结束;
Readln;
结束。
对于那些有兴趣重复性能测试的人,可以使用Delphi XE将以下内容复制并粘贴到新的控制台项目中
program Project1;
uses
classes,
sysutils,
strutils,
math;
{$APPTYPE CONSOLE}
type
TFloatArray = array[0..7] of Double;
procedure ParseFloats_TheFox(const aFloatStr: string;
var aFloatArray: TFloatArray);
var
lPos: Integer;
lNextPos: Integer;
lPosPositive: Integer;
lPosNegative: Integer;
i: Integer;
lFormatSettings: TFormatSettings;
begin
//do not forget formatsettings, or you will get problems with regional settings
lFormatSettings.DecimalSeparator := '.';
lFormatSettings.ThousandSeparator := ',';
lPos := 1;
for i := 0 to High(aFloatArray) do
begin
lPosPositive := PosEx('+', aFloatStr, lPos + 1);
lPosNegative := PosEx('-', aFloatStr, lPos + 1);
if lPosPositive = 0 then
lNextPos := lPosNegative
else if lPosNegative = 0 then
lNextPos := lPosPositive
else
lNextPos := Min(lPosPositive, lPosNegative);
if lNextPos = 0 then
lNextPos := Length(aFloatStr) + 1;
//aFloatArray[i] := StrToFloat(Copy(aFloatStr, lPos, lNextPos - lPos), lFormatSettings);
WriteLn(StrToFloat(Copy(aFloatStr, lPos, lNextPos - lPos), lFormatSettings));
lPos := lNextPos;
end;
end;
procedure ProcessModBosOutPut_RRUZ(OutPut : string);
var
StringStream : TStringStream;
Parser : TParser;
dValue : Double;
sValue : string;
FormatSettings: TFormatSettings;
begin
FormatSettings.DecimalSeparator :='.';
FormatSettings.ThousandSeparator:=',';
//transform the output string to fit with the TParser logic
OutPut:=StringReplace(OutPut,'+',' ',[rfReplaceAll]); //replace '+' sign with a space
OutPut:=StringReplace(OutPut,'-',' -',[rfReplaceAll]); //insert a empty space after of a '-' sign
StringStream:=TStringStream.Create(OutPut);
Parser:=TParser.Create(StringStream);
try
while Parser.Token <> toEOF do
begin
sValue:=Parser.TokenString; //get the string
dValue:=StrToFloat(sValue,FormatSettings); //convert the string
//do something with the float value
Writeln(FloatToStr(dValue));
Parser.NextToken;
end;
finally
Parser.Free;
StringStream.Free;
end;
end;
procedure Jorn(const floatstring: string);
var
i,idx: Integer;
tmpArray: Array[0..7] of Double;
tmpString: ShortString;
begin
DecimalSeparator := '.';
idx := Low(tmpArray);
tmpString := '';
tmpString := floatstring[1];
for i := 2 to Length(floatstring) do
begin
if floatstring[i] in ['+', '-']
then begin
writeln(strtofloat(tmpString));
//TryStrToFloat(tmpString, tmpArray[idx]);
Inc(idx);
tmpString := floatstring[i];
end
else begin
tmpString := tmpString + floatstring[i];
end;
end;
//TryStrToFloat(tmpString, tmpArray[idx]);
writeln(strtofloat(tmpString));
end;
//call like this
var
lFloats: TFloatArray;
I: Integer;
begin
for I := 0 to 999 do
begin
ParseFloats_TheFox ('+0020.8+0022.8-00.046-00.002-00.005-001.99+00.000+00.003', lFloats);
WriteLn('The Fox');
ProcessModBosOutPut_RRUZ('+0020.8+0022.8-00.046-00.002-00.005-001.99+00.000+00.003');
WriteLn('RRUZ');
Jorn ('+0020.8+0022.8-00.046-00.002-00.005-001.99+00.000+00.003');
WriteLn('Jorn');
end;
readln;
end.
程序项目1;
使用
班级,
sysutils,
支柱,
数学;
{$APPTYPE控制台}
类型
TFloatArray=双精度数组[0..7];
过程解析浮点数(const aflautstr:string;
var AFLOATARY:TFLOATARY);
变量
lPos:整数;
lNextPos:整数;
lPosPositive:整数;
lPosNegative:整数;
i:整数;
l格式设置:t格式设置;
开始
//不要忘记格式设置,否则您将在区域设置中遇到问题
lFormatSettings.DecimalSeparator:='.';
lFormatSettings.ThousandSeparator:=',';
LPO:=1;
对于i:=0到高(漂浮数组)do
开始
lPosPositive:=PosEx(+',aFloatStr,lPos+1);
lPos阴性:=PosEx('-',aFloatStr,lPos+1);
如果lPosPositive=0,则
lNextPos:=lPosNegative
否则,如果lPosNegative=0,则
lNextPos:=LpoPositive
其他的
lNextPos:=Min(lPosPositive,lPosNegative);
如果lNextPos=0,则
lNextPos:=长度(漂浮长度)+1;
//aFloatArray[i]:=StrToFloat(复制(aFloatStr,lPos,lNextPos-lPos),lFormatSettings);
WriteLn(StrToFloat(拷贝(aFloatStr、lPos、lNextPos-lPos)、lFormatSettings));
lPos:=lNextPos;
结束;
结束;
过程进程modbosoutput_RRUZ(输出:字符串);
变量
StringStream:TStringStream;
解析器:TParser;
d值:双倍;
sValue:字符串;
格式设置:t格式设置;
开始
FormatSettings.DecimalSeparator:='.';
FormatSettings.MilliandSeparator:=',';
//转换输出字符串以适应TParser逻辑
输出:=StringReplace(输出“+”,“[rfReplaceAll])//将“+”符号替换为空格
输出:=StringReplace(输出'-','-',[rfReplaceAll])//在“-”号后面插入空格
StringStream:=TStringStream.Create(输出);
解析器:=TParser.Create(StringStream);
尝试
while Parser.toedo的标记
开始
sValue:=Parser.TokenString//获取字符串
dValue:=StrToFloat(sValue,FormatSettings)//转换字符串
//用浮点值做些什么
Writeln(FloatToStr(dValue));
Parser.NextToken;
结束;
最后
解析器。免费;
StringStream.免费;
结束;
结束;
过程Jorn(常量floatstring:string);
变量
i、 idx:整数;
tmpArray:Double的数组[0..7];
tmpString:短字符串;
开始
小数分隔符:='';
idx:=低(tmpArray);
tmpString:='';
tmpString:=floatstring[1];
对于i:=2到长度(floatstring)do
开始
如果浮动字符串[i]位于['+','-']
然后开始
writeln(strtofloat(tmpString));
//trystrtofolat(tmpString,tmpArray[idx]);
公司(idx),;
tmpString:=floatstring[i];
结束
否则开始
tmpString:=tmpString+floatstring[i];
结束;
结束;
//trystrtofolat(tmpString,tmpArray[idx]);
writeln(strtofloat(tmpString));
结束;
//像这样打电话
变量
lFloats:TFloatArray;
I:整数;
开始
对于I:=0到999 do
开始
解析浮箱('+0020.8+0022.8-00.046-00.002-00.005-001.99+00.000+00.003',lFloats);
WriteLn(“狐狸”);
ProcessModBos输出_RRUZ(“+0020.8+0022.8-00.046-00.002-00.005-001.99+00.000+00.003”);
书面形式(“RRUZ”);
乔恩(“+0020.8+0022.8-00.046-00.002-00.005-001.99+00.000+00.003”);
书面形式(“Jorn”);
结束;
readln;
结束。
如果您想调用sscanf,我只需调用msvcrt.dll中的一个,它是一个官方的Windows系统
program Project1;
uses
classes,
sysutils,
strutils,
math;
{$APPTYPE CONSOLE}
type
TFloatArray = array[0..7] of Double;
procedure ParseFloats_TheFox(const aFloatStr: string;
var aFloatArray: TFloatArray);
var
lPos: Integer;
lNextPos: Integer;
lPosPositive: Integer;
lPosNegative: Integer;
i: Integer;
lFormatSettings: TFormatSettings;
begin
//do not forget formatsettings, or you will get problems with regional settings
lFormatSettings.DecimalSeparator := '.';
lFormatSettings.ThousandSeparator := ',';
lPos := 1;
for i := 0 to High(aFloatArray) do
begin
lPosPositive := PosEx('+', aFloatStr, lPos + 1);
lPosNegative := PosEx('-', aFloatStr, lPos + 1);
if lPosPositive = 0 then
lNextPos := lPosNegative
else if lPosNegative = 0 then
lNextPos := lPosPositive
else
lNextPos := Min(lPosPositive, lPosNegative);
if lNextPos = 0 then
lNextPos := Length(aFloatStr) + 1;
//aFloatArray[i] := StrToFloat(Copy(aFloatStr, lPos, lNextPos - lPos), lFormatSettings);
WriteLn(StrToFloat(Copy(aFloatStr, lPos, lNextPos - lPos), lFormatSettings));
lPos := lNextPos;
end;
end;
procedure ProcessModBosOutPut_RRUZ(OutPut : string);
var
StringStream : TStringStream;
Parser : TParser;
dValue : Double;
sValue : string;
FormatSettings: TFormatSettings;
begin
FormatSettings.DecimalSeparator :='.';
FormatSettings.ThousandSeparator:=',';
//transform the output string to fit with the TParser logic
OutPut:=StringReplace(OutPut,'+',' ',[rfReplaceAll]); //replace '+' sign with a space
OutPut:=StringReplace(OutPut,'-',' -',[rfReplaceAll]); //insert a empty space after of a '-' sign
StringStream:=TStringStream.Create(OutPut);
Parser:=TParser.Create(StringStream);
try
while Parser.Token <> toEOF do
begin
sValue:=Parser.TokenString; //get the string
dValue:=StrToFloat(sValue,FormatSettings); //convert the string
//do something with the float value
Writeln(FloatToStr(dValue));
Parser.NextToken;
end;
finally
Parser.Free;
StringStream.Free;
end;
end;
procedure Jorn(const floatstring: string);
var
i,idx: Integer;
tmpArray: Array[0..7] of Double;
tmpString: ShortString;
begin
DecimalSeparator := '.';
idx := Low(tmpArray);
tmpString := '';
tmpString := floatstring[1];
for i := 2 to Length(floatstring) do
begin
if floatstring[i] in ['+', '-']
then begin
writeln(strtofloat(tmpString));
//TryStrToFloat(tmpString, tmpArray[idx]);
Inc(idx);
tmpString := floatstring[i];
end
else begin
tmpString := tmpString + floatstring[i];
end;
end;
//TryStrToFloat(tmpString, tmpArray[idx]);
writeln(strtofloat(tmpString));
end;
//call like this
var
lFloats: TFloatArray;
I: Integer;
begin
for I := 0 to 999 do
begin
ParseFloats_TheFox ('+0020.8+0022.8-00.046-00.002-00.005-001.99+00.000+00.003', lFloats);
WriteLn('The Fox');
ProcessModBosOutPut_RRUZ('+0020.8+0022.8-00.046-00.002-00.005-001.99+00.000+00.003');
WriteLn('RRUZ');
Jorn ('+0020.8+0022.8-00.046-00.002-00.005-001.99+00.000+00.003');
WriteLn('Jorn');
end;
readln;
end.