Ich habe einen C++ Builder XE5-Code, den ich in Delphi konvertiere. Obwohl ich in der Lage bin zu kompilieren, scheint der Wert von KeyNum in meinem Delphi-Code immer 0 zurückzugeben. Das Problem könnte im Parsen der Strings liegen.C++ - String-Parsing nach Delphi
Die Funktion nimmt eine Textdatei und überträgt die Informationen in eine C++ - Struktur. Ich habe das in Delphi in eine gepackte Platte konvertiert.
C++ Code
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-Code (Korrigiert)
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;
Die Textdatei Daten sehen so etwas wie diese
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
ich glaube, das Problem ist, dass das C++ Tokens [ 0] .ToInt() Wert von KeyNum hat einen Wert, während mein Delphi StrToInt (Token [0]) immer 0 zurückgibt.
Ich würde mich freuen, wenn mir jemand mit diesem Code helfen kann und wo ich falsch gelaufen bin.
Wir danken Ihnen im Voraus.
Tun Sie einige Debugging nächste –
Statt 'string.ToInt', schauen Sie, welches Ergebnis Sie erhalten, wenn Sie' TryStrToInt' verwenden. IOW, debuggen. –
Danke Rudi. Werde das versuchen. – AndyC