C 到德尔福/帕斯卡
我需要将一段 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。
I need to translate a piece of C code into Delphi/Pascal code, however I'm having trouble understanding a couple of lines.
C Code:
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 ;
}
My current translation:
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 is creating a copy of the ctype parameter and make it lowercase.
Some details regarding translation are highly appreciated, like 'bdy = (char*) ctype + ( ptr - lctype ) + 1;' and the for loop.
FYI I'm translating mod_upload.c.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
所以...
( ptr - lctype )
是指针算术,用于查找lctype
ptr
点的距离。它是指针中保存的地址之间的差异,除以它们指向的数据类型的大小(在本例中为char
,因此大小仅为1
)。因此
bdy = (char*) ctype + ( ptr - lctype ) + 1;
将bdy
指向之前找到的'='
后面的字符,但使用原始字符串ctype
而不是小写副本lctype
。在 C 中,这并不是一种非常奇怪的迭代字符串的方式。在迭代时,
ptr
指向每个字符,而*ptr
给出该字符;因此,当到达终止空字节以结束循环时,*ptr
将测试为FALSE
。++ptr
是更多的指针算术,用于移动到下一个字符的指针。即使这看起来很混乱,但在 C 中这是一种非常自然的方法。因此循环会遍历
bdy
指向的字符串的每个字符,并且在每次迭代期间*ptr 访问当前字符。
看来循环的目的是在找到的下一个分号或空白字符处终止字符串(通过放置较早的空终止符)。
当涉及到字符串操作时,Delphi 和 C 之间有足够的差异,您可能最好只是弄清楚函数在做什么,然后从头开始编写一个等效的 Delphi,而不是尝试直接翻译它像这样。
看起来该函数在
ctype
中查找“边界”(不区分大小写),然后跳过找到的下一个“=”,并返回从那里到下一个分号或空格字符的所有内容的副本。如果您愿意先转换字符串,您可以在 Delphi 中使用 Delphi 字符串和函数轻松地执行相同的操作,使用非常不同的代码...此外,如果重要的话,原始 C 代码看起来会忽略“边界”之间的任何内容" 和 "=" - 所以它会接受“
boundary asdf jidlsah;lkdsf =Value
”以及“boundary=Value
”So...
( ptr - lctype )
is pointer arithmetic to find how far intolctype
ptr
points. It's the difference between the addresses held in the pointers, divided by the size of the data type they point at (in this casechar
, so that size is just1
).So
bdy = (char*) ctype + ( ptr - lctype ) + 1;
pointsbdy
at the character following the'='
found previously, but in the original stringctype
instead of the lowercase copylctype
.This is not a terribly strange way to iterate through a string in C.
ptr
points to each character while iterating through, and*ptr
gives the character; so*ptr
will test asFALSE
when the terminating null byte is reached to end the loop.++ptr
is more pointer arithmetic to move to the pointer to the next character. Even if this seems messy, it's a pretty natural way to do it in C.So the loop moves through each character of the string pointed to by
bdy
, and during each iteration*ptr
accesses the current character.It appears the purpose of the loop was to terminate the string (by placing an earlier null terminator) at the next semicolon or whitespace character found.
There's enough difference between Delphi and C when it comes to string manipulation that you might be better off just figuring out what the function is doing, and then writing a Delphi equivalent from scratch rather than trying to translate it directly like this.
It looks like the function looks for "boundary" (case insensitively) in
ctype
, then skips past the next "=" found, and returns a copy of everything from there up to the next semicolon or whitespace character. You could do the same thing in Delphi easily with Delphi strings and functions, using very different code if you're willing to convert the strings first...Also, if it matters, it looks like the original C code ignores anything between "boundary" and "=" -- so it would accept, say, "
boundary asdf jidlsah;lkdsf =Value
" as well as "boundary=Value
"ptr
是lctype
中“边界”后面的“=”符号的位置,因此ptr - lctype
是距lctype
到这个特定的“=”符号。因此,ctype + (ptr-lctype) + 1
是原始字符串中此“=”符号之后的第一个字符的位置。这样做可能是为了搜索子字符串,同时忽略字符的大小写。一个简单的
strncasecmp()
就可以达到相同的效果。它确实是一个循环,但它没有使用索引变量并通过 bdy[i] 访问字符串,而是使用临时指针 ptr。该指针迭代
bdy
指向的字符串。它从第一个字符开始,一直持续到到达字符串末尾(即,如果*ptr
计算结果为 0(在 C 中,字符串以 null 终止)),并递增循环指针每次迭代后加 1。使用指针代替索引变量是 C 语言中的常见习惯用法,许多人更喜欢使用简单的 for (i=0; i < strlen(bdy); i++) ,因为它可以节省调用
strlen()
。对你来说不幸的是,我 15 年前就停止了 Pascal 编程,所以我无法帮助你翻译。不过,既然您知道这两行的含义,那就应该没问题了。
ptr
is the location of the "="-sign following "boundary" withinlctype
, henceptr - lctype
is the distance from the start oflctype
to this specific "="-sign. Thus,ctype + (ptr-lctype) + 1
is the location of the first character after this "="-sign in the original string.This has probably been done in order to search for substrings while ignoring the case of the characters. A simple
strncasecmp()
may have accomplished the same effect.It's indeed a loop, but instead of using an index variable and accessing the string by
bdy[i]
, it uses a temporary pointer,ptr
. This pointer iterates over the string pointed to bybdy
. It starts at the first character, continues until the end of the string is reached (that is, if*ptr
evaluates to 0 (in C, strings are null-terminated)), and increments the loop pointer by 1 after each iteration.Using a pointer instead of an index variable is a common idiom in C, and preferred by many over the naive
for (i=0; i < strlen(bdy); i++)
, since it saves the call tostrlen()
.Unfortunately for you, I stopped programming in Pascal 15 years ago, so I can't help you with the translation. However, it should be no problem, now that you know what those two lines mean.