【问题标题】:C to Delphi/PascalC 到 Delphi/Pascal
【发布时间】:2012-02-06 06:24:19
【问题描述】:

我需要将一段 C 代码翻译成 Delphi/Pascal 代码,但是我无法理解几行代码。

C 代码:

static char* get_boundary(apr_pool_t* p, const char* ctype) {
  char* ret = NULL ;
  if ( ctype ) {
    char* lctype = lccopy(p, ctype) ;
    char* bdy = strstr(lctype, "boundary") ;
    if ( bdy ) {
      char* ptr = strchr(bdy, '=') ;
      if ( ptr ) {
    // what is the following line supposed to do?
    bdy = (char*) ctype + ( ptr - lctype ) + 1;
    // and this? I understand it's a loop, but *ptr and ++ptr is ugly!
    for ( ptr = bdy; *ptr; ++ptr )
      if ( *ptr == ';' || isspace(*ptr) )
        *ptr = 0 ;
    ret = apr_pstrdup(p, bdy) ;
      }
    }
  }
  return ret ;
}   

我目前的翻译:

function get_boundary(p: Papr_pool_t; const ctype: PChar): PChar;
var
  LCType: PChar;
  LBody: PChar;
begin
  Result := NIL;
  LCType := lccopy(p, ctype);
  LBody := strpos(LCType, 'boundary');
  if LBody <> NIL then begin
    // now what? (:
  end; // if LBody <> NIL then begin
end;

lccopy 正在创建 ctype 参数的副本并将其设为小写。

非常感谢有关翻译的一些细节,例如 'bdy = (char*) ctype + ( ptr - lctype ) + 1;'和 for 循环。

仅供参考,我正在翻译 mod_upload.c。

【问题讨论】:

  • 也许你可以写一些胶水代码来从 Pascal 调用你的 C 代码!
  • @BasileStarynkevitch 我不喜欢到处使用鸭带,此外,这将有助于我更好地理解 C。
  • 1.使用string 而不是PChar。 C 没有字符串对象。不要让 C 的能力驱动你的 Delphi 设计。 2.strchrstrstr与Delphi的Pos作用相同。
  • @DavidHeffernan 谢谢,不知道!
  • Dorin,我喜欢你的“duck tape”拼写;-)

标签: c delphi pascal freepascal


【解决方案1】:
        bdy = (char*) ctype + ( ptr - lctype ) + 1;

所以... ( ptr - lctype ) 是指针算术,用于查找到 lctype ptr 点的距离。这是指针中保存的地址之间的差异,除以它们指向的数据类型的大小(在本例中为char,因此大小仅为1)。

所以bdy = (char*) ctype + ( ptr - lctype ) + 1;bdy 指向之前找到的'=' 后面的字符,但在原始字符串ctype 中,而不是小写副本lctype

        for ( ptr = bdy; *ptr; ++ptr )

在 C 中迭代字符串并不是一种非常奇怪的方法。ptr 在迭代时指向每个字符,*ptr 给出字符;所以当到达终止空字节以结束循环时,*ptr 将测试为FALSE++ptr 是更多的指针运算,用于移动到指向下一个字符的指针。即使这看起来很混乱,但在 C 中这是一种非常自然的方式。

因此循环遍历bdy 指向的字符串的每个字符,并在每次迭代期间*ptr 访问当前字符。

          if ( *ptr == ';' || isspace(*ptr) )
            *ptr = 0 ;

循环的目的似乎是在找到的下一个分号或空白字符处终止字符串(通过放置一个较早的空终止符)。


在字符串操作方面,Delphi 和 C 之间有足够的差异,您最好先弄清楚函数在做什么,然后从头开始编写 Delphi 等效项,而不是尝试直接这样翻译吧。

看起来该函数在ctype 中查找“边界”(不区分大小写),然后跳过找到的下一个“=”,并返回从那里到下一个分号或空白字符的所有内容的副本。如果您愿意先转换字符串,则可以使用非常不同的代码在 Delphi 中轻松地使用 Delphi 字符串和函数执行相同的操作...

另外,如果重要的话,看起来原始 C 代码忽略了“边界”和“=”之间的任何内容——所以它会接受,比如,“boundary asdf jidlsah;lkdsf =Value”以及“boundary=Value

【讨论】:

  • +1 100% 同意“最好只是弄清楚函数在做什么,然后从头开始编写一个 Delphi 等价物,而不是直接翻译它”
  • +1 并被接受,谢谢 Dimitri 的出色回答,还有一件事,*ptr 像取消引用吗?
  • 是的,这正是它的本质——ptr 是指针,*ptr 取消引用它以访问它所指向的内容。
【解决方案2】:
// what is the following line supposed to do?
bdy = (char*) ctype + ( ptr - lctype ) + 1;

ptrlctype 内“边界”之后的“=”符号的位置,因此ptr - lctype 是从lctype 的开头到这个特定的“=”符号的距离。因此,ctype + (ptr-lctype) + 1 是原始字符串中此“=”符号之后的第一个字符的位置。

这可能是为了在忽略字符大小写的情况下搜索子字符串。一个简单的strncasecmp() 也可能达到同样的效果。

// and this? I understand it's a loop, but *ptr and ++ptr is ugly!
for ( ptr = bdy; *ptr; ++ptr )

这确实是一个循环,但它没有使用索引变量并通过bdy[i] 访问字符串,而是使用了一个临时指针ptr。该指针遍历bdy 指向的字符串。它从第一个字符开始,一直持续到到达字符串的末尾(即,如果*ptr 的计算结果为 0(在 C 中,字符串以空值结尾)),并在每次迭代后将循环指针递增 1。

使用指针而不是索引变量是 C 中的一个常见习惯用法,并且比幼稚的 for (i=0; i &lt; strlen(bdy); i++) 更受许多人的青睐,因为它节省了对 strlen() 的调用。

很遗憾,我在 15 年前就停止了 Pascal 编程,所以我无法帮你翻译。不过应该没问题了,既然你知道这两行是什么意思了。

【讨论】:

  • +1 谢谢菲利普,很好的回答,不幸的是,迪米特里的回答很相似,而且快了 1 小时,但你非常接近!
猜你喜欢
  • 1970-01-01
  • 2013-01-21
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-08
  • 2013-09-12
相关资源
最近更新 更多