字符串连接功能,请求注释。 [英] String concatenation function, request for comments.

查看:58
本文介绍了字符串连接功能,请求注释。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这篇文章的目的是获取社区对

有用性,效率的看法,最重要的是这个

小块代码的正确性。我感谢你们在

考虑这篇文章的时间,以及你们的评论。


我写了这个函数来简化组合字符串的任务

混合来源。我经常看到sprintf()的使用导致了几行代码的b
,以及比任务实际上更多的处理。

这个函数非常直接,它接受一个

参数的变量列表,以包含总数

参数数量的强制整数开头。


该函数分配一个静态缓冲;我认为使用malloc()

是不必要的,因为释放内存的责任将是留给客户端的
。这种设计选择还可以最大限度地减少所需参数的数量。如果在第二次调用函数之后需要生成缓冲区,则可以将其复制到客户端的另一个缓冲区

题外话。


如果为串联指定的字符串超出了可用的缓冲区,

整个字符串将被截断。我决定这个

行为因为我不相信输出对于

程序操作是必不可少的,所以这个错误在大多数情况下可以保持沉默,但是

一旦检查结果,对程序员来说仍然是显而易见的。


如果定义的缓冲量不足或不必要的大量

特殊应用,由客户重新定义

缓冲量;我觉得512字节足以供我使用。


我觉得这个功能最常用于经常形成消息,因为

使用套接字,这不会否则可以重复使用。


功能的使用示例:


char * tmp;

tmp = vast( 欢迎来到,主机,,您以,名称,。登录;


send(sockfd,tmp,strlen(tmp) ),0);


该函数定义如下:


/ * ------------ -------------------------------------------------- ---- * \

| - vast():变量参数字符串;连接任意字符串。 - |

\ * ------------------------------------- ----------------------------- * /


#define VAST_BUF 512


char * vast(int num,...){


static char buf [VAST_BUF];


int t = 0,

o = 0;


char * v;


va_list ap;


if(num> 1){

va_start(ap,num);


/ *循环它虽然很热。 * /


while(num--){

v = va_arg(ap,char *);


/ *将字符串复制到累积缓冲区,直到达到NUL * /

/ *只要总数不超过(MAX_BUF - 1)。 * /


while((buf [o] = * v ++)&&!(t> = VAST_BUF - 1)){

/ *满足条件,增量偏移和总计。 * /

t ++,o ++;

}

}


va_end(ap); < br $>
}


buf [o] = NUL;


return(buf);


}

The purpose of this post is to obtain the communities opinion of the
usefulness, efficiency, and most importantly the correctness of this
small piece of code. I thank everyone in advance for your time in
considering this post, and for your comments.

I wrote this function to simplify the task of combining strings using
mixed sources. I often see the use of sprintf() which results in
several lines of code, and more processing than really for the task.
The function is pretty straight forward, it accepts a variable list of
arguments beginning with the mandatory integer containing the total
number of arguments.

The function allocates a static buffer; I thought the use of malloc()
to be unnecessary, as the responsibility of freeing the memory would be
left to the client. This design choice also minimizes the amount of
required arguments. If the resultant buffer is needed beyond the second
call to the function, it can be copied to another buffer at the clients
digression.

If the strings specified for concatenation exceed the buffer available,
the overall string will simply be truncated. I decided on this
behaviour because I do not believe the output to be essential to a
programs operation, so this error can in most cases go silent, but
still be apparent to the programmer once the result is examined.

If the defined buffer amount is insufficient or is unnecessarily large
for a particular application, it is left to the client to redefine the
buffer amount; I feel that 512 bytes is sufficient for my use.

I find this function most useful when frequently forming messages for
use over a socket, which will not otherwise be reused.

Example use of the function:

char *tmp;
tmp = vast("Welcome to ", HOST, ", you are logged in as ", name, ".");

send(sockfd, tmp, strlen(tmp), 0);

The function is defined as follows:

/*------------------------------------------------------------------*\
|- vast(): Variable Argument String; concatenate arbitrary strings. -|
\*------------------------------------------------------------------*/

#define VAST_BUF 512

char *vast(int num, ...) {

static char buf[VAST_BUF];

int t = 0,
o = 0;

char *v;

va_list ap;

if(num > 1) {
va_start(ap, num);

/* Loop it while its hot. */

while(num--) {
v = va_arg(ap, char *);

/* Copy string to cumulative buffer until NUL is reached */
/* so long as the total does not exceed (MAX_BUF - 1). */

while((buf[o] = *v++) && !(t >= VAST_BUF - 1)) {
/* Condition is met, increment offset and total. */
t++, o++;
}
}

va_end(ap);
}

buf[o] = NUL;

return(buf);

}

推荐答案

> char * tmp;
> char *tmp;
tmp = vast(" Welcome to",HOST,",您以&,; name,"。")登录;);


第一个参数是一个整数而不是一个字符串。我个人会更改

它所以你不必指定参数的数量并且这样做:


vast(a," b"," c",(char *)0);

#define VAST_BUF 512

char * vast(int num,...){


我建议size_t num,但那只是我。

静态字符buf [VAST_BUF];

int t = 0,
o = 0;


摆脱t。

char * v;


const char *并在循环内移动

va_list ap;


将此移至if

if(num> 1){


if(num> 0)

va_start(ap,num);

/ *在热的时候循环它。 * /

while(num--){
v = va_arg(ap,char *);


const char *

/ *将字符串复制到累积缓冲区,直到达到NUL * /
/ *只要总数不超过(MAX_BUF - 1)。 * /


什么是MAX_BUF?

while((buf [o] = * v ++)&&!(t> = VAST_BUF - 1)){
/ *满足条件,增量偏移和总数。 * /
t ++,o ++;
}


更改为:


while(buf [o] = * v ++){

if(++ o> = sizeof(buf)/ sizeof(buf [0]) - 1){

num = 0;

休息;

}

}

}

va_end(ap);
}

buf [o] = NUL;


只需使用''\0''或0.

return(buf);
}
tmp = vast("Welcome to ", HOST, ", you are logged in as ", name, ".");
First parameter is an integer not a string. I personally would change
it so you don''t have to specify the number of parameters and do:

vast("a", "b", "c", (char*)0);
#define VAST_BUF 512

char *vast(int num, ...) {
I suggest size_t num, but that''s just me.
static char buf[VAST_BUF];

int t = 0,
o = 0;
get rid of t.
char *v;
const char * and move this inside the loop
va_list ap;
move this inside the if
if(num > 1) {
if (num > 0)
va_start(ap, num);

/* Loop it while its hot. */

while(num--) {
v = va_arg(ap, char *);
const char *
/* Copy string to cumulative buffer until NUL is reached */
/* so long as the total does not exceed (MAX_BUF - 1). */
What''s MAX_BUF?
while((buf[o] = *v++) && !(t >= VAST_BUF - 1)) {
/* Condition is met, increment offset and total. */
t++, o++;
}
Change this to:

while (buf[o] = *v++) {
if (++o >= sizeof(buf)/sizeof(buf[0])-1) {
num = 0;
break;
}
}
}

va_end(ap);
}

buf[o] = NUL;
Just use ''\0'' or 0.
return(buf);
}






2005年6月5日06:09:49 -0700,mi *********** @ gmail.com

< mi *********** @ gmail.com>写道:


" Me"已发布好评,我想补充以下内容:
On 5 Jun 2005 06:09:49 -0700, "mi***********@gmail.com"
<mi***********@gmail.com> wrote:

"Me" already posted good comments, I''d like to add the following :
static char buf [VAST_BUF];
static char buf[VAST_BUF];




您确实意识到,只要您的程序执行多任务处理,使用静态缓冲区就可能导致行为不良行为? (两个

线程可能同时执行你的功能,在你的缓冲区中造成一个

混乱)。


这样的错误有一个很难找到的倾向(因为大部分的时间都是按照预期进行的,如果发生错误,它就会接近

重现它。)


你的功能不是重入 (没有使用静态数据的功能是

重入)。


我认为将指针传递给

目标缓冲区及其长度的指示。



You do realize that using a static buffer will be a possible cause of
bad behaviour as soon as your program does some multitasking? (two
threads could be executing your function at the same time, making a
mess in your buffer).

Such errors have a tendency to be hard to find (since most of the
time, things go as expected and, if the error occurs, it''s near
impossible to reproduce it).

Your function is not "re-entrant" (no function using static data is
re-entrant).

I think it would be better and more flexible to pass a pointer to a
destination buffer and an indication of its length.


mi *********** @ gmail.com 写道:
mi***********@gmail.com wrote:
这篇文章的目的是获取社区认为有用性,效率,以及最重要的是这段小代码的正确性。我提前感谢大家在
考虑这篇文章以及你的评论。

我写了这个函数来简化使用混合源组合字符串的任务。我经常看到sprintf()的使用导致了几行代码,并且处理的内容比实际的更多。
该函数非常简单,它接受一个变量列表
以包含参数总数的强制整数开头的参数。

该函数分配一个静态缓冲区;我认为使用malloc()
是不必要的,因为释放内存的责任将留给客户端。这种设计选择还最大限度地减少了所需参数的数量。如果在第二次调用函数之后需要生成的缓冲区,则可以将其复制到客户端的另一个缓冲区中。


ITYM自由裁量权 - 但我离题了。

如果为连接指定的字符串超出了可用的缓冲区,
整个字符串将被截断。我决定这个行为,因为我不相信输出对于程序操作是必不可少的,所以这个错误在大多数情况下都可以保持沉默,但对于程序员来说仍然是显而易见的检查结果。


这对我来说是一个糟糕的设计选择。基本上,你是

说长串联字符串仅用于装饰性

目的,并且是不重要的。正确运行

计划。换句话说,合同的一部分。对于你的

函数是不要将它用于任何重要的东西。这限制了函数的有用性(你询问的属性之一);

例如,使用函数生成

数据库查询。即使是涉及人类读者的某些用途也是不安全的:想象一下在你的文字上收到一条消息

寻呼机说紧急!肥料已经播出空气了b $ b循环器!删除所有内容并立即与我见面

如果特定应用程序定义的缓冲区数量不足或不必要的大,
将由客户端重新定义
缓冲量;我觉得512字节足以供我使用。

我经常发现这个函数在经常形成用于在套接字上使用的消息时非常有用,否则将无法重复使用。

该函数的使用示例:

char * tmp;
tmp = vast(欢迎使用,HOST,以&,登录, name,。;);


这表明界面的脆弱性。它是你的

功能和你的界面设计,在你的第一个例子中,它使用了你的b $ b你犯了一个错误。当这样的事情发生在我身上

(没有人完美)时,我开始怀疑我设计的界面是否应该重新设计。


就个人而言,我不喜欢需要编码器计算的界面

的东西 - 它可以追溯到我早期的FORTRAN时代,当时我不得不写作

字符串为13HHELLO,WORLD!并希望我没有吹它。

发送(sockfd,tmp,strlen(tmp),0);

该功能定义如下: />
/ * ------------------------------------------ ------------------------ * \
| - vast():变量参数字符串;连接任意字符串。 - |
\ * ----------------------------------------- ------------------------- * /

#define VAST_BUF 512

char * vast (int num,...){

静态字符buf [VAST_BUF];

int t = 0,
o = 0;


保持两个变量的价值

总是相等的是什么?

char * v;

va_list ap;


你没有#include''d< stdarg.h>,所以这不会编译。

if(num> 1){


特殊选择:如果有人试图连接只有一个

字符串(`p = vast(1,Alpha and Omega)''),他将获得空的

字符串作为回报。

va_start(ap,num);

/ *在热的时候循环它。 * /

while(num--){
v = va_arg(ap,char *);

/ *将字符串复制到累积缓冲区,直到达到NUL * /
/ *只要总数不超过(MAX_BUF - 1)。 *(

while((buf [o] = * v ++)&&!(t> = VAST_BUF - 1)){


Can你找到一种比较模糊的方式来写't< VAST_BUF - 1''?

/ *满足条件,增量偏移和总计。 * /
t ++,o ++;
}
}

va_end(ap);
}

buf [o] = NUL;


NUL尚未定义。假设你打算将它定义为
为零,那么名称NUL就是一个误称:你在某些特定的编码中确实*不想要某些特定字符,你想要

零值字符而不管编码 - ASCII,EBCDIC,

你的名字。


另外:只有当'num''开头时少于两个
时才需要这个作业。

return(buf);

}
The purpose of this post is to obtain the communities opinion of the
usefulness, efficiency, and most importantly the correctness of this
small piece of code. I thank everyone in advance for your time in
considering this post, and for your comments.

I wrote this function to simplify the task of combining strings using
mixed sources. I often see the use of sprintf() which results in
several lines of code, and more processing than really for the task.
The function is pretty straight forward, it accepts a variable list of
arguments beginning with the mandatory integer containing the total
number of arguments.

The function allocates a static buffer; I thought the use of malloc()
to be unnecessary, as the responsibility of freeing the memory would be
left to the client. This design choice also minimizes the amount of
required arguments. If the resultant buffer is needed beyond the second
call to the function, it can be copied to another buffer at the clients
digression.
ITYM "discretion" -- but I digress.
If the strings specified for concatenation exceed the buffer available,
the overall string will simply be truncated. I decided on this
behaviour because I do not believe the output to be essential to a
programs operation, so this error can in most cases go silent, but
still be apparent to the programmer once the result is examined.
This strikes me as a poor design choice. Essentially, you are
saying that long concatenated strings are only for "decorative"
purposes, and are "unimportant" to the correct operation of the
program. To put it another way, part of the "contract" for your
function is "Don''t use this for anything important." This limits
the function''s usefulness (one of the attributes you asked about);
for example, it would be unsafe to use the function to generate
database queries. It would be unsafe even for some uses where a
human reader is involved: Imagine getting a message on your text
pager that said "Emergency! The fertilizer has hit the air
circulator! Drop everything and meet me right away at"
If the defined buffer amount is insufficient or is unnecessarily large
for a particular application, it is left to the client to redefine the
buffer amount; I feel that 512 bytes is sufficient for my use.

I find this function most useful when frequently forming messages for
use over a socket, which will not otherwise be reused.

Example use of the function:

char *tmp;
tmp = vast("Welcome to ", HOST, ", you are logged in as ", name, ".");
This demonstrates a fragility of the interface. It''s YOUR
function and YOUR interface design, and in YOUR very first example
of its use you''ve made an error. When such things happen to me
(nobody''s perfect), I start to wonder whether the interface I''ve
designed should perhaps be redesigned.

Personally, I dislike interfaces that require the coder to count
things -- it dates from my early FORTRAN days, when I had to write
character strings as 13HHELLO, WORLD! and hope that I hadn''t blown it.
send(sockfd, tmp, strlen(tmp), 0);

The function is defined as follows:

/*------------------------------------------------------------------*\
|- vast(): Variable Argument String; concatenate arbitrary strings. -|
\*------------------------------------------------------------------*/

#define VAST_BUF 512

char *vast(int num, ...) {

static char buf[VAST_BUF];

int t = 0,
o = 0;
What''s the point of maintaining two variables whose values
are always equal?
char *v;

va_list ap;
You haven''t #include''d <stdarg.h>, so this won''t compile.
if(num > 1) {
Peculiar choice: if somebody tries to "concatenate" just one
string (`p = vast(1, "Alpha and Omega")''), he''ll get the empty
string in return.
va_start(ap, num);

/* Loop it while its hot. */

while(num--) {
v = va_arg(ap, char *);

/* Copy string to cumulative buffer until NUL is reached */
/* so long as the total does not exceed (MAX_BUF - 1). */

while((buf[o] = *v++) && !(t >= VAST_BUF - 1)) {
Can''t you find a more obscure way to write `t < VAST_BUF - 1''?
/* Condition is met, increment offset and total. */
t++, o++;
}
}

va_end(ap);
}

buf[o] = NUL;
NUL has not been defined. Assuming you intend to define it
as zero, the name `NUL'' is a misnomer: you do *not* want some
particular character in some particular encoding, you want the
zero-valued character regardless of encoding -- ASCII, EBCDIC,
you name it.

An aside: This assignment is required only if `num'' was
less than two to begin with.
return(buf);

}




摘要:我不喜欢这个设计 - 但这在某种程度上是个人品味的问题关于哪个合理的人可以

不同意。实施是可以的,一旦缺少一些

件就像< stdarg.h>和NUL供应,但可以制作

更清楚。文件不足;特别是,价值

511是外部界面的一部分,但没有在任何地方描述,

和单串连接的令人惊讶的处理

值得一提。实用性:最小化。效率:无法承受

标准C.正确性:由于缺乏规格而无法承担。


- -

Eric Sosman
es ***** @ acm-dot-org .inva 盖子


这篇关于字符串连接功能,请求注释。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆