C++;Delphi的字符串解析 我有一个C++ Builder XE5代码,我正在转换成Delphi。虽然我能够编译,但在我的Delphi代码中,KeyNum的值似乎总是返回0。问题可能出在字符串的解析中 函数取一个文本文件并将信息传递给C++结构体。我用Delphi把它转换成一张打包的唱片

C++;Delphi的字符串解析 我有一个C++ Builder XE5代码,我正在转换成Delphi。虽然我能够编译,但在我的Delphi代码中,KeyNum的值似乎总是返回0。问题可能出在字符串的解析中 函数取一个文本文件并将信息传递给C++结构体。我用Delphi把它转换成一张打包的唱片,c++,string,delphi,parsing,C++,String,Delphi,Parsing,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(&Start

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;
}

我认为问题是,KyNUM的C++令牌[0 ] .toTin()值有一个值,而我的Delphi StuttIn(TokEns[0)]始终返回0。p> 如果有人能帮我处理这段代码和我的错误,我将不胜感激


先谢谢你

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

当填充
X
/
Y
/
比例
/
方向
值时,每次读取
令牌[TokenPos]
后,都不会增加
TokenPos

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

在读取
X
值之前,您正在递增
TokenPos
,这是错误的。您正在跳过
标记[0]
中的值。C++代码使用的是增量增量,而不是增量增量。
另一方面,您还泄漏了
CreateProcess()
返回的两个句柄。您必须在
ProcInfo.hThread
上调用
CloseHandle()
,并在
WaitForSingleObject()
返回后调用
ProcInfo.hproces
。您应该等待
ProcInfo.hproces
而不是
ProcInfo.hThread
每次读取
List.Strings[LinePos]
后,您都不会增加
LinePos

当填充
X
/
Y
/
比例
/
方向
值时,每次读取
令牌[TokenPos]
后,都不会增加
TokenPos

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

在读取
X
值之前,您正在递增
TokenPos
,这是错误的。您正在跳过
标记[0]
中的值。C++代码使用的是增量增量,而不是增量增量。
另一方面,您还泄漏了
CreateProcess()
返回的两个句柄。您必须在
ProcInfo.hThread
上调用
CloseHandle()
,并在
WaitForSingleObject()
返回后调用
ProcInfo.hproces
。您应该等待
ProcInfo.hProcess
而不是
ProcInfo.hThread

下一步进行一些调试,而不是
string.ToInt
,看看如果使用
TryStrToInt
会得到什么结果。瞧,调试,谢谢你,鲁迪。下一步做一些调试,而不是使用
string.ToInt
,看看使用
TryStrToInt
会得到什么结果。瞧,调试,谢谢你,鲁迪。我来试试。非常感谢你的指点,雷米。我已经更新了Delphi代码以反映问题,它似乎按照预期工作。非常感谢您的指点,Remy。我已经更新了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