急! 帮忙翻译一个简单C函数为delphi(300)

Discussion in '请您翻译' started by 小伶, Jul 21, 2009.

  1. 小伶

    小伶 Member

    Apr 1, 2015
    int getmystr(char *s, char *dl, char *gg[], int len){ int n = 1;
    gg [0] = s;
    while (*s != '/0') { if ((strchr(dl, (int) *s) != NULL) && n < len) {/* extern char *strchr(char *s,char c);
    查找字符串s中首次出现字符c的位置 返回首次出现c的位置的指针,如果s中不存在c则返回NULL。 /n 回车换行 /r 回车 /0 结尾*/ *s = '/0';
    while (*(s + 1) != '/0' && strchr (dl, (int) *(s + 1)) != NULL) s++;
    gg[n++] = s + 1;
    } if (*s == '/n' || *s == '/r') { *s = '/0';
    break;
    } s++;
    } if (n < len) gg[n] = NULL;
    return (n);}
     
  2. zk

    zkktom Member

    Apr 1, 2015
    何必呢? pos函数不就可以解决问题吗?
     
  3. lu

    luoyanqing119 Member

    Apr 1, 2015
    改改数据结构中类型的申明,逻辑控制改一下就可以了。-----------无论是条件和循环,常用的这几种语言都有对应的控制方式
     
  4. wq

    wql Member

    Apr 1, 2015
    function getmystr(s:string;dl:char;gg:pchar;len:integer):integer;var n:integer;
    begin
    n:= 1;
    while (s<>'')do
    brgin if ((strchr(dl, (int) *s) != NULL) and n<len) then
    /* extern char *strchr(char *s,char c);
    查找字符串s中首次出现字符c的位置 返回首次出现c的位置的指针,如果s中不存在c则返回NULL。 /n 回车换行 /r 回车 /0 结尾*/ delete(s,1,1);
    while (s<>'' and strchr (dl, (int) *(s + 1)) != NULL)do
    delete(s,1,1);
    inc(n);
    end;
    if (s[1] = #13 or s[1] = #10) then
    begin
    delete(s,1,1);
    break;
    end;
    delete(s,1,1);
    end;
    result:=n;
    end;
     
  5. ha

    hanyuhen1 Member

    Apr 1, 2015
    设 s := '爷爷,,奶奶,,,,,,,爸爸,,,妈妈,,,me';
    dl := ',';那么执行后gg[0] := '爷爷';gg[1] := '奶奶';gg[2] := '爸爸';gg[3] := '妈妈';gg[4] := 'me';没看出来那段C语言能实现这个效果;我觉得只能是这样设 s := 'a,,bb,,,,,,,cc,,,dd,,,me';gg[0] := a;gg[1] := b;gg[2] := c;gg[3] := d;gg[4] := m;
     
  6. 小伶

    小伶 Member

    Apr 1, 2015
    to hanyuhen1:我是为了生动说明才打这样的比喻......
     
  7. 小伶

    小伶 Member

    Apr 1, 2015
    还有的就是, 原C函数貌似存在内存泄露?用第2次就会出问题.所以, 不是很简单的......
     
  8. 轻舞肥羊

    轻舞肥羊 Member

    Apr 1, 2015
    delphi有现成的函数,也没内存问题,为啥不用呢procedure TForm1.Button4Click(Sender: TObject);var s : string;
    gg : array of string;
    lst : TStrings;
    i : Integer;
    begin
    s := '爷爷,,奶奶,,,,,,,爸爸,,,妈妈,,,me';
    lst := TStringList.Create;
    try ExtractStrings([','], [], PChar(s), lst);
    SetLength(gg, lst.Count);
    for i := 0 to lst.Count - 1do
    gg := lst;
    finally lst.Free;
    end;
    for i := 0 to High(gg)do
    memo1.Lines.Add(gg);
    end;
     
  9. 关门放狗

    关门放狗 Member

    Apr 1, 2015
    function getmystr(s:pChar;dl:pChar;
    arrText: array of pchar;len:Integer):Integer;var n:Word;
    begin
    arrText[0]:=s;
    while (Integer(s^)<>0)do
    begin
    // if ((strchr(dl, (int) *s) != NULL) && n < len) { if (Pos(string(s^),StrPas(dl))>0) and (n<len) then
    begin
    s^:=#0;
    while ((s+1)^<>'0') and (Pos(string((s+1)^),StrPas(dl))>0)do
    Inc(s);
    inc(n);
    arrText[n]:=s+1;
    end;
    if (s^=#13) and (s^=#10) then
    begin
    s^:=#0;
    exit;
    end;
    end;
    end;
    没给出具体调用不好调试 ,这个有问题哦
     
  10. wa

    wangdonghai Member

    Apr 1, 2015
    //下面的代码只处理分隔符为一个字符的情况procedure GetMyStr(s:pChar;dl:char);var c:array[0..255] of char;
    p:pChar;
    i1,i2:Integer;
    begin
    p:=s;
    i1:=0;
    i2:=0;
    while p^<>#0do
    begin
    if p^=dl then
    begin
    if i2-i1>1 then
    begin
    StrLCopy(c,s+i1,i2-i1);
    showmessage(c);
    end;
    i1:=i2+1;
    end;
    inc(p);
    inc(i2);
    end;
    if i1<i2 then
    //末尾没有分隔符 begin
    StrLCopy(c,s+i1,i2-i1);
    showmessage(c);
    end;
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    GetMyStr(PChar('爷爷,,奶奶,,,,,,,爸爸,,,妈妈,,,me'),',');
    end;
     
  11. 小伶

    小伶 Member

    Apr 1, 2015
    谢谢各位的回复 谢谢wql函数看起来简单 实际有点复杂.结果是为了分割出非空的与分割符dl不相同的字符串, 然后存放在gg数组中.设 s := '爷爷,,奶奶,,,,,,,爸爸,,,妈妈,,,me';
    dl := ',';那么执行后gg[0] := '爷爷';gg[1] := '奶奶';gg[2] := '爸爸';gg[3] := '妈妈';gg[4] := 'me';我自己写了一个, 实现了这个结果, 但是感觉不是最好的翻译.因为整个C函数关键之关键在一句 *s = '/0';
    由于delphi的指针运用没C那么灵活, 所以, 直译不成, 我只好意译了.function GetMyStr(s, dl: string;
    var gg: Array of string;
    Len: Integer) : Integer;var i, n, l: Integer;
    str: string;
    begin
    for i := Low(gg) to High(gg)do
    gg := '';
    n := 0;
    l := length(s);
    str := '';
    for i:=1 to ldo
    begin
    if s <> dl then
    begin
    str := str + s;
    if (i <= Len) then
    // and ((i + 1) < l) if (length(str) > 0) and ((i = l) or (i = Len) or (s[i + 1] = dl)) then
    begin
    gg[n] := str;
    inc(n);
    str := '';
    end;
    end;
    end;
    Result := n + 1;
    // + 1 是为了跟C代码一致end;
    哪位朋友能原汁原味的把这个C函数翻译出来马上结帖.要求: 1.用指针.2.string不要, 要用pchar. 因为这个函数要被很多个函数调用到, 我改为string是不得以之举.
     
  12. wa

    wangdonghai Member

    Apr 1, 2015
    //修改前的函数不能处理 '爷爷,,奶奶,,,,,,,爸爸,,,妈妈,,,me,.'//需要修改procedure GetMyStr(s:pChar;dl:char);var c:array[0..255] of char;
    p:pChar;
    i1,i2:Integer;
    begin
    p:=s;
    i1:=0;
    i2:=0;
    while p^<>#0do
    begin
    if (p^=dl) then
    begin
    if (i2-i1<>0) and ((s+i1)<>dl) then
    begin
    StrLCopy(c,s+i1,i2-i1);
    showmessage(c);
    end;
    i1:=i2+1;
    end;
    inc(p);
    inc(i2);
    end;
    if i1<i2 then
    //末尾没有分隔符 begin
    StrLCopy(c,s+i1,i2-i1);
    showmessage(c);
    end;
    end;
     
  13. 小伶

    小伶 Member

    Apr 1, 2015
    谢谢 wangdonghaiprocedure GetMyStr4(s: PChar;
    dl: char);var c: array[0..255] of char;
    p: PChar;
    i1, i2: Integer;
    begin
    p := s;
    i1 := 0;
    i2 := 0;
    while p^ <> #0do
    begin
    if (p^ = dl) then
    begin
    if (i2 - i1 <> 0) and ((s + i1) <> dl) then
    begin
    StrLCopy(c, s + i1, i2 - i1);
    Form1.Memo1.Lines.Add(c);
    end;
    i1 := i2 + 1;
    end;
    inc(p);
    inc(i2);
    end;
    if i1 < i2 then
    //末尾没有分隔符 begin
    StrLCopy(c, s + i1, i2 - i1);
    Form1.Memo1.Lines.Add(c);
    end;
    end;
    procedure TForm1.Button18Click(Sender: TObject);
    begin
    GetMyStr4('爷999,,奶奶88,,,,,,,爸爸,,,妈妈,,,me', ',');
    end;
    ============================================我自己试了轻舞肥羊的办法 把 ExtractStrings 封装进来 但是s只能用string了, 速度和算法还是不够理想.function getmystr3(s : string;
    dl: PChar;
    var gg: array of string;
    len: Integer): Integer;var lst: TStrings;
    i: Integer;
    s1: string;
    begin
    Result := 0;
    for i := Low(gg) to High(gg)do
    gg := '';
    if len > length(s) then
    exit;
    s1 := copy(s, 1, len);
    lst := TStringList.Create;
    try ExtractStrings([dl^], [], PChar(s1), lst);
    //SetLength(gg, lst.Count);
    // High(gg) for i := 0 to lst.Count - 1do
    gg := lst;
    Result := lst.Count;
    finally lst.Free;
    end;
    end;
    procedure TForm1.Button16Click(Sender: TObject);var n, i, j: Integer;
    gg: Array[0..8] of string;// [0..19]begin
    n := getmystr3('爷999,,奶奶88,,,,,,,爸爸,,,妈妈,,,me', ',', gg, 33);
    for i := 0 to High(gg)do
    Form1.Memo1.Lines.Add(gg);
    Memo1.Lines.Add(format('一共分割几个: n = %d', [n]));
    end;
     
  14. 小伶

    小伶 Member

    Apr 1, 2015
    谢谢 轻舞肥羊, ExtractStrings让我见识到Borland公司的程序员写代码是多么厉害, 对比我和他的翻译, 真是天壤之别.谢谢 关门放狗, 我要的就是这种风格的翻译.但是您翻译的这个函数试验了一下是死循环.谢谢 wangdonghai 您的翻译也是另一种不错的思路.整理如下:// Borland公司的程序员:function ExtractStrings(Separators, WhiteSpace: TSysCharSet;
    Content: PChar;
    Strings: TStrings): Integer;var Head, Tail: PChar;
    EOS, InQuote: Boolean;
    QuoteChar: Char;
    Item: string;
    begin
    Result := 0;
    if (Content = nil) or (Content^=#0) or (Strings = nil) then
    Exit;
    Tail := Content;
    InQuote := False;
    QuoteChar := #0;
    Strings.begin
    Update;
    try repeat while Tail^ in WhiteSpace + [#13, #10]do
    Tail := StrNextChar(Tail);
    Head := Tail;
    while Truedo
    begin
    while (InQuote and not (Tail^ in [QuoteChar, #0])) or not (Tail^ in Separators + [#0, #13, #10, '''', '"'])do
    Tail := StrNextChar(Tail);
    if Tail^ in ['''', '"'] then
    begin
    if (QuoteChar <> #0) and (QuoteChar = Tail^) then
    QuoteChar := #0 else
    if QuoteChar = #0 then
    QuoteChar := Tail^;
    InQuote := QuoteChar <> #0;
    Tail := StrNextChar(Tail);
    end else
    Break;
    end;
    EOS := Tail^ = #0;
    if (Head <> Tail) and (Head^ <> #0) then
    begin
    if Strings <> nil then
    begin
    SetString(Item, Head, Tail - Head);
    Strings.Add(Item);
    end;
    Inc(Result);
    end;
    Tail := StrNextChar(Tail);
    until EOS;
    finally Strings.EndUpdate;
    end;
    end;
    procedure TForm1.Button12Click(Sender: TObject);var s : string;
    gg : array of string;
    lst : TStrings;
    i : Integer;
    begin
    s := '爷爷,,奶奶,,,,,,,爸爸,,,妈妈,,,me';
    lst := TStringList.Create;
    try ExtractStrings([','], [], PChar(s), lst);
    SetLength(gg, lst.Count);
    for i := 0 to lst.Count - 1do
    gg := lst;
    finally lst.Free;
    end;
    for i := 0 to High(gg)do
    memo1.Lines.Add(gg);
    end;
    function getmystr(s: PChar;
    dl: PChar;
    arrText: array of pchar;
    len: Integer): Integer;var n: Word;
    begin
    arrText[0] := s;
    while (Integer(s^) <> 0)do
    begin
    // if ((strchr(dl, (int) *s) != NULL) && n < len) { if (Pos(string(s^), StrPas(dl)) > 0) and (n < len) then
    begin
    s^ := #0;
    while ((s + 1)^ <> '0') and (Pos(string((s + 1)^), StrPas(dl)) > 0)do
    Inc(s);
    inc(n);
    arrText[n] := s + 1;
    end;
    if (s^ = #13) and (s^ = #10) then
    begin
    s^ := #0;
    exit;
    end;
    end;
    end;
    procedure TForm1.Button13Click(Sender: TObject);var n, i, j: Integer;
    dl: Array [0..15] of pchar;// [0..19]begin
    n := getmystr('爷爷,,奶奶,,,,,,,爸爸,,,妈妈,,,me', ',', dl, 20);
    Memo1.Lines.Add(format('n = %d %s %s %s %s ', [n, dl[0], dl[1], dl[2], dl[3]]));
    end;
    //下面的代码只处理分隔符为一个字符的情况procedure GetMyStr2(s: PChar;
    dl: char);var c: array[0..255] of char;
    p: PChar;
    i1, i2: Integer;
    begin
    p := s;
    i1 := 0;
    i2 := 0;
    while p^ <> #0do
    begin
    if p^ = dl then
    begin
    if i2 - i1 > 1 then
    begin
    StrLCopy(c, s + i1, i2 - i1);
    showmessage(c);
    end;
    i1 := i2 + 1;
    end;
    inc(p);
    inc(i2);
    end;
    if i1 < i2 then
    //末尾没有分隔符 begin
    StrLCopy(c, s + i1, i2 - i1);
    showmessage(c);
    end;
    end;
    procedure TForm1.Button14Click(Sender: TObject);
    begin
    GetMyStr2(PChar('爷爷,,奶奶,,,,,,,爸爸,,,妈妈,,,me'),',');
    end;
    我还想看看各位处理字符串的高手还要没有其他更理想的翻译, 再等一两天再结贴吧.谢谢您们!
     
  15. 小伶

    小伶 Member

    Apr 1, 2015
  16. 关门放狗

    关门放狗 Member

    Apr 1, 2015
    var Form1: TForm1;
    dl: array of WideString;
    // [0..19]function getmystr(s: PWideChar;
    dl: PWideChar;
    var arrText: array of WideString;
    len: Integer): Integer;var n: Integer;
    tmp: PWideChar;
    dlstr:string;
    begin
    n := 0;
    tmp := s;
    if (s^ <> #0) then
    begin
    dlstr:= WideCharToString(dl);
    while ((s + 1)^ <> #0) and (Pos(dlstr, s + 1) > 0)do
    begin
    if Trim(Copy(s, 0, Pos(dlstr, s) - 1)) <> '' then
    begin
    arrText[n] := Copy(s, 0, Pos(dlstr, s) - 1);
    n := n + 1;
    end;
    s := s + Pos(dlstr, s);
    end;
    if ((Pos(dlstr, s + 1) = 0) and ((s + 1)^ <> #0)) then
    arrText[n] := RightStr(tmp, Length(WideCharToString(tmp)) - LastDelimiter(dlstr, WideCharToString(tmp)));
    result := n + 1;
    end else
    result := n// if n < len then
    arrText[n] := '';
    end;
    procedure TForm1.Button1Click(Sender: TObject);var i: Integer;
    begin
    SetLength(dl, 15);
    // i := getmystr('爷爷,,奶奶,,,,,,,爸爸,,,妈妈,,,me,goudan,123', ',', dl, 20);
    i := getmystr('爷爷, ,奶奶,,', ' ', dl, 20);
    Memo1.Lines.Add(format('n = %d, %s', [i, dl[0]]));
    // Memo1.Lines.Add(format('n = %d, %s, %s, %s, %s ', [i, dl[0], dl[1], dl[2], dl[3]]));
    end;
     
  17. 小伶

    小伶 Member

    Apr 1, 2015
    function getmystr6(s: PWideChar;
    dl: PWideChar;
    var arrText: array of WideString;
    len: Integer): Integer;var n: Integer;
    tmp: PWideChar;
    dlstr: string;
    begin
    n := 0;
    tmp := s;
    if (s^ <> #0) then
    begin
    dlstr := WideCharToString(dl);
    while ((s + 1)^ <> #0) and (Pos(dlstr, s + 1) > 0)do
    begin
    if Trim(Copy(s, 0, Pos(dlstr, s) - 1)) <> '' then
    begin
    arrText[n] := Copy(s, 0, Pos(dlstr, s) - 1);
    n := n + 1;
    end;
    s := s + Pos(dlstr, s);
    end;
    if ((Pos(dlstr, s + 1) = 0) and ((s + 1)^ <> #0)) then
    arrText[n] := RightStr(tmp, Length(WideCharToString(tmp)) - LastDelimiter(dlstr, WideCharToString(tmp)));
    result := n + 1;
    end else
    result := n // if n < len then
    arrText[n] := '';
    end;
    procedure TForm1.Button20Click(Sender: TObject);var i, n: Integer;
    gg: array of WideString;
    // [0..19]begin
    SetLength(gg, 7);
    n := getmystr6('爷爷,,奶奶,,,,,,,爸爸,,,妈妈,,,me,goudan,123', ',', gg, 44);
    for i := 0 to High(gg)do
    Form1.Memo1.Lines.Add(gg);
    Memo1.Lines.Add(format('n = %d', [n]));
    end;
    十分感谢 关门放狗sizeof(PChar) = 4sizeof(PAnsiChar) = 4sizeof(PWideChar) = 4PChar指向null结束的Char字符串的指针,类似于C的char*或lpstr类型。 PAnsiChar指向null结束的AnsiChar字符串的指针。 PWideChar指向null结束的WideChar字符串的指针。在C语言的 char *, 翻译为delphi, PChar, PAnsiChar, PWideChar的字节都相同, 究竟哪种比较好呢? 用PWideChar是否有什么考虑?
     
  18. 关门放狗

    关门放狗 Member

    Apr 1, 2015
    D7是ANSICHAR 2009是UNICODE D7中的很多函数是基于ANSICHAR 对UNICODE会有问题 所以转换了一下。 说实话我对内存理解的还很不到位,只是有个模糊的概念,内部具体是什么,怎么布局还是一脑袋浆糊。
     
  19. 关门放狗

    关门放狗 Member

    Apr 1, 2015
    我的方法有点 脱裤放屁找麻烦的感觉 确实不用转换 直接用PCHAR就OK[:(][:(]
     
  20. 小伶

    小伶 Member

    Apr 1, 2015
    十分感谢各位分数有限 略表意思