我的gets_ws功能 [英] My gets_ws function

查看:46
本文介绍了我的gets_ws功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

int gets_ws(char * buff,int maxlen,int sc,FILE * fh);


此函数从fh读取最多maxlen个字符,当它停止时

遇到空格,sc或EOF。如果遇到EOF,函数

将返回EOF。


如果buff为NULL,则读取的字符将被丢弃。否则,它们将被放入buff中。在NULL缓冲区的情况下,该函数返回读取的字符数或

0。


我在XML解析器中使用它来读取标记名称:

gets_ws(buff,max,''>'',fh);

如果它读取最大字符数(通过返回最大值),我只需删除

其余字符:

gets_ws(NULL,0,''>'',fh);


这是代码:


gets_ws.c:

/ *从流向上读取直到第一个空格或sc字符。 *

*如果给出一个非NULL缓冲区,它将填充它。否则,它*

*将简单地通过角色扔掉它们。 *

*返回读取的字符数或失败时的EOF。 * /

static int gets_ws(char * buff,size_t maxlen,int sc,FILE * fh)

{

int i = 0;

int ch = fgetc(fh);


断言(fh!= NULL);

if(buff == NULL )

{

while(!isspace(ch)&& ch!= sc)

ch = fgetc(fh);


ungetc(ch);

返回0;

}


而( i<(maxlen - 1)&&!isspace(ch)&& ch!= sc)

{

if(ch == EOF)

返回EOF;


buff [i] = ch;

++ i;


ch = fgetc(fh);

}

ungetc(ch);


返回i;

}


欢迎提出意见或建议。


-

Andrew Poelstra< ; http://www.wpsoftware.net/projects/>

要给我发电子邮件,请使用apoelstra。在上述领域。

你们人讨厌数学。 - James Harris

解决方案

Andrew Poelstra< ap ******* @ localhost.localdomainwrote:


int gets_ws(char * buff,int maxlen,int sc,FILE * fh);


此函数从fh读取最多maxlen个字符,停止时它

遇到空白,sc或EOF。如果遇到EOF,函数

将返回EOF。


如果buff为NULL,则读取的字符将被丢弃。否则,它们将被放入buff中。在NULL缓冲区的情况下,该函数返回读取的字符数或

0。



< snip>


if(buff == NULL)

{

while(!isspace(ch)&& ; ch!= sc)

ch = fgetc(fh);


ungetc(ch);

返回0;

}



< snip>


这个丢弃循环还应该检查一下EOF,不应该吗?


/ Michael Brennan


Andrew Poelstra说:


int gets_ws(char * buff,int maxlen,int sc,FILE * fh);



让我们给maxlen一个size_t,好吗?我们不想再去/那里了!


gets_ws.c:

/ *从流向上读取直到第一个空格或sc字符。 *

*如果给出一个非NULL缓冲区,它将填充它。否则,它*

*将简单地通过角色扔掉它们。 *

*返回读取的字符数或失败时的EOF。 * /

static int gets_ws(char * buff,size_t maxlen,int sc,FILE * fh)

{

int i = 0;

int ch = fgetc(fh);



这里有一个使用getc而不是fgetc的情况。因为标准的getc被给予

显式许可,不止一次地评估它的参数

当作为宏实现时(fgetc是* not *给出的许可),它可能

可能让实现者更快地使getc。可能不是很多b $ b,但要注意这一点。


>

断言(fh!= NULL);

if(buff == NULL)

{

while(!isspace(ch)& & ch!= sc)



其他人已经注意到这里没有检查EOF。


ch = fgetc(fh);


ungetc(ch);

返回0;

}



在这里,你可以简单地将while循环中的

括在''else''块中。


>

while(i<(maxlen - 1)&&!isspace(ch)&& ch! = sc)



如果maxlen为0怎么办?


{

if(ch == EOF)

返回EOF;


buff [i] = ch;

++ i;



buff [i ++] = ch;在语义上等同于上面两行,并且

足够简单和惯用,它不会让任何维护

代码的人感到困惑。

< snip>


-

Richard Heathfield

Usenet是一个奇怪的地方 - dmr 29/7/1999
http://www.cpax.org.uk

电子邮件:rjh在上面的域名(但显然放弃了www)


2006-07-11,Richard Heathfield < in ***** @ invalid.invalidwrote:


Andrew Poelstra说:


> ; int gets_ws(char * buff,int maxlen,int sc,FILE * fh);



让我们为maxlen设置size_t,不是吗?我们不想去/那里/再次!



我确实有一个size_t,但后来我在

函数并且不希望我的lint因为比较size_t和

int而惹我生气,或者其他东西。 (回想起来,这可能是一个

的案例,其中一个明确的演员是值得的。)


我会解决它。
< blockquote class =post_quotes>


> gets_ws.c:
/ *从流向上读取直到第一个空格或sc字符。 *
*如果给出非NULL缓冲区,它将填充该缓冲区。否则,* *
*将简单地通过角色并扔掉它们。 *
*返回读取的字符数或失败时的EOF。 * /
static int gets_ws(char * buff,size_t maxlen,int sc,FILE * fh)
{i / 0;
int ch = fgetc(fh);



这里有一个使用getc而不是fgetc的情况。因为标准的getc被给予

显式许可,不止一次地评估它的参数

当作为宏实现时(fgetc是* not *给出的许可),它可能

可能让实现者更快地使getc。可能不是很多b $ b,但是要记住这一点。



直觉表明getc在stdin工作获得

的方式(并且put,putc在stdout上工作)。对于维护程序员,恕我直言,这可能会让人感到困惑。


>>
assert(fh!= NULL);
if(buff == NULL)
{while /(/ isspace(ch)&& ch!= sc)



其他人已经注意到这里没有检查EOF。



和/那是我发布的原因这对clc。因为我的所有目的,我已经亲自验证了输入,我从来没有在测试中发现



> ch = fgetc(fh);

ungetc(ch);
返回0;
}



而不是ungetcing ch并返回0,你可以简单地将

跟随while循环包含在''else''块中。



是的,那会更清楚,不是吗。


>>
while(i< ;(maxlen - 1)&&!isspace(ch)&& ch!= sc)



如果maxlen为0怎么办?



i< -1会失败,因为我最初为0.我确实检查了这个条件。

然而,它会设置为buff [0]到''\0'',即使我'' m告诉

buff有0,而不是1个字节。我相信另一个断言()在这里是



> {
if(ch == EOF)
返回EOF;

buff [i] = ch;
++ i;



buff [i ++] = ch;在语义上等同于上面两行,并且

足够简单和惯用,它不会让任何维护

代码的人感到困惑。



Okey doke。谢谢!


-

Andrew Poelstra< http://www.wpsoftware.net/projects/>

要给我发电子邮件,请使用apoelstra。在上述领域。

你们人讨厌数学。 - 詹姆斯哈里斯


int gets_ws (char *buff, int maxlen, int sc, FILE *fh);

This function reads up to maxlen characters from fh, stopping when it
encounters whitespace, sc, or EOF. If EOF is encountered, the function
returns EOF.

If buff is NULL, read characters are discarded. Otherwise, they are
put into buff. The function returns the number of characters read or
0 in the case of a NULL buffer.

I use it in my XML parser to read a tag name:
gets_ws (buff, max, ''>'', fh);
and if it reads max characters (by returning max), I simply delete
the remaining characters:
gets_ws (NULL, 0, ''>'', fh);

Here is the code:

gets_ws.c:
/* Reads from stream up until first whitespace or sc character. *
* If given a non-NULL buffer, it will fill that. Otherwise, it *
* will simply go through the characters and throw them away. *
* Returns number of characters read or EOF on failure. */
static int gets_ws (char *buff, size_t maxlen, int sc, FILE *fh)
{
int i = 0;
int ch = fgetc (fh);

assert (fh != NULL);
if (buff == NULL)
{
while (!isspace (ch) && ch != sc)
ch = fgetc (fh);

ungetc (ch);
return 0;
}

while (i < (maxlen - 1) && !isspace (ch) && ch != sc)
{
if (ch == EOF)
return EOF;

buff[i] = ch;
++i;

ch = fgetc (fh);
}
ungetc (ch);

return i;
}

Comments or suggestions are welcome.

--
Andrew Poelstra <http://www.wpsoftware.net/projects/>
To email me, use "apoelstra" at the above domain.
"You people hate mathematics." -- James Harris

解决方案

Andrew Poelstra <ap*******@localhost.localdomainwrote:

int gets_ws (char *buff, int maxlen, int sc, FILE *fh);

This function reads up to maxlen characters from fh, stopping when it
encounters whitespace, sc, or EOF. If EOF is encountered, the function
returns EOF.

If buff is NULL, read characters are discarded. Otherwise, they are
put into buff. The function returns the number of characters read or
0 in the case of a NULL buffer.

<snip>

if (buff == NULL)
{
while (!isspace (ch) && ch != sc)
ch = fgetc (fh);

ungetc (ch);
return 0;
}

<snip>

This "discard loop" should also have a check for EOF, shouldn''t it?

/Michael Brennan


Andrew Poelstra said:

int gets_ws (char *buff, int maxlen, int sc, FILE *fh);

Let''s have a size_t for maxlen, shall we? We don''t want to go /there/ again!

gets_ws.c:
/* Reads from stream up until first whitespace or sc character. *
* If given a non-NULL buffer, it will fill that. Otherwise, it *
* will simply go through the characters and throw them away. *
* Returns number of characters read or EOF on failure. */
static int gets_ws (char *buff, size_t maxlen, int sc, FILE *fh)
{
int i = 0;
int ch = fgetc (fh);

There is a case for using getc rather than fgetc here. Because getc is given
explicit licence by the Standard to evaluate its argument more than once
when implemented as a macro (a licence that fgetc is *not* given), it may
be possible for the implementor to make getc a bit quicker. Probably not
much in it, but it''s something to bear in mind.

>
assert (fh != NULL);
if (buff == NULL)
{
while (!isspace (ch) && ch != sc)

Someone else has already noted the lack of a check for EOF here.

ch = fgetc (fh);

ungetc (ch);
return 0;
}

Instead of ungetc-ing ch and returning 0 here, you could simply enclose the
following while loop in an ''else'' block.

>
while (i < (maxlen - 1) && !isspace (ch) && ch != sc)

What if maxlen is 0?

{
if (ch == EOF)
return EOF;

buff[i] = ch;
++i;

buff[i++] = ch; is semantically equivalent to the above two lines, and is
sufficiently simple and idiomatic that it won''t confuse anyone maintaining
the code.

<snip>

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)


On 2006-07-11, Richard Heathfield <in*****@invalid.invalidwrote:

Andrew Poelstra said:

>int gets_ws (char *buff, int maxlen, int sc, FILE *fh);


Let''s have a size_t for maxlen, shall we? We don''t want to go /there/ again!

I did have a size_t, but then I was returning -1 in one version of the
function and didn''t want my lint to nab me for comparing a size_t and
int, or something to that effect. (In retrospect, that may have been a
case where an explicit cast was merited.)

I''ll fix it.

>gets_ws.c:
/* Reads from stream up until first whitespace or sc character. *
* If given a non-NULL buffer, it will fill that. Otherwise, it *
* will simply go through the characters and throw them away. *
* Returns number of characters read or EOF on failure. */
static int gets_ws (char *buff, size_t maxlen, int sc, FILE *fh)
{
int i = 0;
int ch = fgetc (fh);


There is a case for using getc rather than fgetc here. Because getc is given
explicit licence by the Standard to evaluate its argument more than once
when implemented as a macro (a licence that fgetc is *not* given), it may
be possible for the implementor to make getc a bit quicker. Probably not
much in it, but it''s something to bear in mind.

Intuition suggests that getc works from stdin in the same way that gets
does (and puts, putc work on stdout). It could potentially be confusing
for a maintenance programmer, IMHO.

>>
assert (fh != NULL);
if (buff == NULL)
{
while (!isspace (ch) && ch != sc)


Someone else has already noted the lack of a check for EOF here.

And /that/ is why I posted this to clc. Since for all my purposes, I
have personally validated the input, I never would have spotted that
in testing.

> ch = fgetc (fh);

ungetc (ch);
return 0;
}


Instead of ungetc-ing ch and returning 0 here, you could simply enclose the
following while loop in an ''else'' block.

Yes, that would be more clear, wouldn''t it.

>>
while (i < (maxlen - 1) && !isspace (ch) && ch != sc)


What if maxlen is 0?

i < -1 will fail, as i is initially 0. I did check that condition.
However, it will then set to buff[0] to ''\0'', even though I''m told
that buff has 0, not 1 bytes. I believe another assert() is in order
here.

> {
if (ch == EOF)
return EOF;

buff[i] = ch;
++i;


buff[i++] = ch; is semantically equivalent to the above two lines, and is
sufficiently simple and idiomatic that it won''t confuse anyone maintaining
the code.

Okey doke. Thanks!

--
Andrew Poelstra <http://www.wpsoftware.net/projects/>
To email me, use "apoelstra" at the above domain.
"You people hate mathematics." -- James Harris


这篇关于我的gets_ws功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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