gpt4 book ai didi

C++ 字符串解析到 Delphi

转载 作者:行者123 更新时间:2023-11-28 02:06:42 25 4
gpt4 key购买 nike

我有一个要转换为 Delphi 的 C++ Builder XE5 代码。虽然我能够编译,但在我的 Delphi 代码中,KeyNum 的值似乎总是返回 0。问题可能出在字符串的解析中。

该函数获取一个文本文件并将信息传输到 C++ 结构。我将其转换为 Delphi 中的打包记录。

C++代码

int __fastcall TFastSift::fastSift(UnicodeString fileName)
{
//
STARTUPINFO StartInfo; // name structure
PROCESS_INFORMATION ProcInfo; // name structure
memset(&ProcInfo, 0, sizeof(ProcInfo)); // Set up memory block
memset(&StartInfo, 0 , sizeof(StartInfo)); // Set up memory block
StartInfo.cb = sizeof(StartInfo); // Set structure size
//UnicodeString app = "C:\\windows\\system32\\cmd.exe";
//
UnicodeString app = getenv("COMSPEC");
//
UnicodeString args = "/C "+progPath+"siftfast.exe <"+workPath+fileName+".pgm>"+workPath+fileName+".kds";
StartInfo.dwFlags = STARTF_USESHOWWINDOW;
StartInfo.wShowWindow = SW_HIDE;
int res = CreateProcessW(app.w_str(), args.w_str(), NULL, NULL, NULL, NULL, NULL, NULL, &StartInfo, &ProcInfo); // starts MyApp
if (res)
{
WaitForSingleObject(ProcInfo.hThread, INFINITE);
}
//
//TODO: check if file kds existis
//
TStringList *list = new TStringList(this);
list->LoadFromFile(workPath+fileName+".kds");
FormatSettings.DecimalSeparator = '.';
if (list->Count < 1)
{
// error
delete list;
return 0;
}
TStringDynArray tokens;
// key num, key length
tokens = SplitString(list->Strings[0], " ");
int line_pos, tok_pos;
int keynum = tokens[0].ToInt();
kfDesc = new FeatureDescriptor[keynum];
UnicodeString line, tok_test;
line_pos = 1;
for (int i = 0; i < keynum; i++) //
{
line = list->Strings[line_pos++];
tokens = SplitString(line, " ");
tok_pos = 0;
try {
kfDesc[i].x = tokens[tok_pos++].ToDouble(); // x
kfDesc[i].y = tokens[tok_pos++].ToDouble(); // y
kfDesc[i].scale = tokens[tok_pos++].ToDouble(); // scale
kfDesc[i].orientation = tokens[tok_pos++].ToDouble(); // orientation
// values
tok_pos = 0;
while (tok_pos < KLEN)
{
line = list->Strings[line_pos++];
tokens = SplitString(line, " ");
int tok_len = tokens.get_length() - 1; // usually 16
for (int j = 0; j < tok_len; j++)
{
tok_test = tokens[j];
kfDesc[i].value[tok_pos] = tokens[j].ToDouble();
tok_pos++;
}
}
line_pos++; // skip separator line
}
catch (...) {
keynum = 0;
break;
}
}
delete list;
return keynum;
}

Delphi 代码(更正)

function TFastSift.FastSift(const FileName: string): Integer;
var
StartInfo: TStartupInfo;
ProcInfo: TProcessInformation;
ApplicationName: string;
CommandLine: string;
Created: Boolean;
List: TStringList;
Tokens: TArray<string>;
LinePos: Integer;
TokenPos: Integer;
KfDesc: TArrOfTFeatureDescriptor;
Line: string;
TokenTest: string;
I: Integer;
TokenLen: Integer;
KeyNum: Integer;
J: Integer;
begin
FillChar(ProcInfo, SizeOf(ProcInfo), 0); // Set up memory block
FillChar(StartInfo, SizeOf(StartInfo), 0); // Set up memory block
StartInfo.cb := SizeOf(StartInfo); // Set structure size
ApplicationName := GetEnvironmentVariable('COMSPEC');
CommandLine := '/C ' + FProgPath + 'siftfast.exe <' + FWorkPath + FileName + '.pgm>' + FWorkPath + FileName + '.kds';
StartInfo.dwFlags := STARTF_USESHOWWINDOW;
StartInfo.wShowWindow := SW_HIDE;
Created := CreateProcess(PChar(ApplicationName), PChar(CommandLine), nil, nil, False, 0, nil, nil, StartInfo, ProcInfo); // starts MyApp
if (Created) then
begin
try
WaitForSingleObject(ProcInfo.hProcess, INFINITE);
finally
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
end;
end;

//
// TODO: check if file kds existis
//
List := TStringList.Create();
try
List.LoadFromFile(TPath.Combine(FWorkPath, FileName + '.kds'));
FormatSettings.DecimalSeparator := '.';
if (List.Count < 1) then
begin
// error
Exit(0);
end;

// key num, key length
Tokens := List.Strings[0].Split([' ']);
KeyNum := StrToInt(Tokens[0]);

SetLength(KfDesc, KeyNum);
LinePos := 1;
for I := 0 to KeyNum - 1 do
begin
Line := List.Strings[LinePos];
Tokens := Line.Split([' ']);
TokenPos := 0;
try
KfDesc[I].X := StrToFloat(Tokens[TokenPos]); // x
inc(TokenPos);
KfDesc[I].Y := StrToFloat(Tokens[TokenPos]); // y
inc(TokenPos);
KfDesc[I].Scale := StrToFloat(Tokens[TokenPos]); // scale
inc(TokenPos);
KfDesc[I].Orientation := StrToFloat(Tokens[TokenPos]); // orientation
// values
TokenPos := 0;
inc(LinePos);
while (TokenPos < KLEN) do
begin
Line := List.Strings[LinePos];
Tokens := Line.Split([' ']);
TokenLen := Length(Tokens); // usually 16
for J := 0 to TokenLen - 1 do
begin
TokenTest := Tokens[J];
KfDesc[I].Value[TokenPos] := StrToFloat(Tokens[J]);
inc(TokenPos);
end;
inc(LinePos); // skip separator line
end;
inc(LinePos); // skip separator line

except
KeyNum := 0;
break;
end;
end;
finally
List.Free();
end;
Result := KeyNum;
end;

文本文件数据看起来像这样

14219 128
817.027 1573.46 228.737 1.65905
0 0 0 25 41 0 0 0 16 17 19 94 111 0 0 0
140 65 15 11 5 0 0 1 34 5 0 0 0 0 0 0
0 0 0 66 90 5 0 0 44 30 12 140 140 19 0 2
140 55 5 12 4 1 0 8 52 0 0 0 0 0 0 2
0 0 0 64 104 12 0 0 61 5 2 64 140 64 5 20
140 8 0 1 5 5 3 58 44 0 0 0 0 0 0 4
0 0 1 51 81 44 13 0 40 2 1 61 36 30 76 46
140 1 0 1 1 0 13 96 20 0 0 0 0 0 0 4

712.401 2643.9 183.285 1.45477
0 0 5 32 54 116 16 0 106 24 3 12 63 135 13 15
135 43 0 0 0 1 1 8 10 1 0 0 0 0 0 0
0 4 53 70 106 15 1 0 69 29 35 78 125 39 11 12
135 74 1 5 5 1 3 23 24 3 0 0 0 0 0 0
0 0 16 21 111 94 79 10 19 3 15 25 20 19 135 98
135 7 0 1 1 1 66 135 15 0 0 0 0 0 0 5
0 0 0 0 2 26 48 3 0 0 0 0 0 2 91 23
0 0 0 0 0 0 21 22 0 0 0 0 0 0 0 0

我认为问题在于 KeyNum 的 C++ tokens[0].ToInt() 值有一个值,而我的 Delphi StrToInt(Tokens[0]) 始终返回 0。

如果有人能帮助我解决这段代码以及我哪里出错了,我将不胜感激。

在此先感谢您。

最佳答案

每次从 List.Strings[LinePos] 读取后,您都不会递增 LinePos

填充 X/Y/Scale/Orientation 值时,您不会递增 每次从 Tokens[TokenPos] 读取之后的 TokenPos

C++ 代码执行这些增量。

您在读取 ​​X 值之前递增 TokenPos,这是错误的。您正在跳过 Tokens[0] 中的值。 C++ 代码使用后增量,而不是前增量。

附带说明一下,您还泄漏了 CreateProcess() 返回的两个句柄。在 WaitForSingleObject() 返回后,您必须在 ProcInfo.hThreadProcInfo.hProcess 上调用 CloseHandle()。您应该等待 ProcInfo.hProcess 而不是 ProcInfo.hThread

关于C++ 字符串解析到 Delphi,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37202634/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com