getc()与fgetc() [英] getc() vs. fgetc()

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

问题描述

我确定之前已经问过这个问题,我已经查看了常见问题解答,但是我要求b $ b寻找以下内容的解释:

函数对:


gets()/ fgets()

puts()/ fputs()

printf()/ fprintf()

scanf()/ fscanf()

的不同之处主要在于第一个假定stdin / stdout而第二个

一个与程序员传递的流一起工作。这是有道理的,并使

功能易于记忆。


然后我们有:


getc( )/ fgetc()

putc()/ fputc()

getchar()/ fgetchar()

putchar()/ fputchar()


在每种情况下,这对函数执行相同的任务。对于那些一直没有使用这些功能的人来说这很难实现,因为

每当他们使用一个他们必须查找的时候是否会假设其中一个

标准流与否。是否有理由认为该标准没有采用这些函数的一致(且非常有用)的命名约定?


解决方案



" William L. Bahn" <无线***** @ toomuchspam.net>在消息中写道

新闻:10 ************* @ corp.supernews.com ...

我很确定这个之前已被问到,我已查看常见问题解答,但我正在寻找以下解释:

功能对:

gets()/ fgets()
puts()/ fputs()
printf()/ fprintf()
scanf()/ fscanf()

主要区别因为第一个假定stdin / stdout,而
第二个假定程序员传递的流。这很有意义,
使函数易于记忆。

然后我们有:

getc()/ fgetc()
putc() / fputc()
getchar()/ fgetchar()
putchar()/ fputchar()

在每种情况下,这对函数执行相同的任务。这使得那些不能一直使用这些功能的人很难,因为每次使用这些功能时他们都必须查看是否采用了标准流之一。有没有理由说标准没有对这些函数采用
a一致(且非常有用)的命名约定?




是的,fgetc()和fputc( )有意义,但getc()/ putc()应该做什么

getchar()/ putchar()做什么。它实际上甚至可能不如你所说的那么一致。 fputs()的参数是从fprintf()向后反转
(fprintf()必须是那样),fputs()和fgets()的参数不是
匹配,而f匹配在fgetchar()和fputchar()似乎没有提到

任何东西。为了(部分)回答你的问题,后两个函数是

实际上不属于标准。


" William L. Bahn <无线***** @ toomuchspam.net>写道:

函数对:

gets()/ fgets()


不要使用得到()。永远。这是一个无法修复的安全漏洞,因为

没有办法告诉它它的缓冲区停止在哪里它将开始

munge其他变量或更糟糕的..

puts()/ fputs()
printf()/ fprintf()
scanf()/ fscanf()

主要区别在于第一个假设stdin / stdout而第二个
一个与程序员传递的流一起工作。这很有意义,使得功能易于记忆。


但这具有欺骗性。在(f)printf()和

(f)scanf()的情况下都是如此,但是put(s)实际上与

略有不同fputs(s,stdin);

然后我们有:

getc()/ fgetc()
putc()/ fputc()
getchar()/ fgetchar()
putchar()/ fputchar()


不,我们不是。 C中没有fgetchar()和fputchar()这样的东西。

在每种情况下,函数对执行相同的任务。


不,他们不是。 fgetc(instream)从instream中获取一个角色。

getc(instream)表面上做同样的事情,但允许

不止一次评估它的参数。这意味着

fgetc(instream [i ++])是安全的,但是getc(instream [i ++])并不安全;它可能会在两个

序列点之间多次评估i ++,甚至不止一次,从而导致未定义的行为。

的另一面硬币是getc()可能比fgetc()略快。

getchar()相当于getc(stdin)。由于stdin不包含

副作用,这既安全又有效。

fputc()/ putc()/ putchar()/ stdout也是如此,使用

附带条件,putc()只允许评估其第二个参数

而不是一次; putc(line [i ++],outstream)是安全的,但putc(i,

outstream [j ++])不是。

这使得
很难那些不会一直使用这些功能的人,因为每次使用这些功能时,他们都必须查看是否采用了标准流之一。有没有理由说标准没有对这些函数采用一致(且非常有用)的命名约定?




我认为这是出于历史原因;也就是说,因为它是标准C实现之前通常做到的方式,并且更改它会导致现有代码损坏太多。


Richard


In< 10 ************* @ corp.supernews.com> William L. Bahn <无线***** @ toomuchspam.net>写道:

但是我们有:

getc()/ fgetc()
putc()/ fputc()
getchar ()/ fgetchar()
putchar()/ fputchar()

在每种情况下,这对函数执行相同的任务。这使得那些不能一直使用这些功能的人很难,因为每次使用这些功能时他们都必须查看是否采用了标准流之一。有没有理由说标准没有对这些函数采用一致(且非常有用)的命名约定?




命名约定早于标准,并且它是一致的,即使对于那些不熟悉语言历史的人来说也不是很明显。


首先,没有fgetchar和fputchar这样的东西,所以我们只用getc / fgetc和putc / fputc对留下
。两个案例中的f代表函数,一旦你理解了

< stdio.h>的历史就很有意义了。 。


在ANSI之前的日子里,getc和putc通常用宏来实现,

。这对于大多数用途来说已经足够了,除非你需要将他们的地址传递给另一个函数,或者由于某些其他原因,需要一个带有语义的

函数作为这些宏。所以,fgetc和fputc已经引入了作为getc和putc的函数版本的



标准C中的情况有所不同,因为标准中的每个函数都是

C库必须作为一个函数实现,即使它还提供了作为宏的
。所以,你可以获取getc的地址,甚至可以调用getc的

函数版本,如果你足够小心绕过宏。

同样,fgetc而且fputc也可以作为宏提供,虽然我不能想象为什么任何实现者都可能想要这样做。


但即使在今天那里简单版本和f版本之间的细微差别:如果实现为宏,

标准C库中的所有函数都限于每个函数的单个评估他们的

参数。这使putchar(i ++)安全:我保证

增加一次,即使putchar被实现为宏。

但是,有两个例外来自这个规则:getc和putc。如果将

实现为宏,则允许它们多次评估其FILE指针

参数(和*仅*此参数)。因此,在

不太可能的事件中,您需要使用包含副作用的表达式来调用getc / putc作为FILE指针参数,请使用f-version

代替。


Dan

-

Dan Pop

DESY Zezhen,RZ集团

电子邮件: Da*****@ifh.de


I''m sure this has been asked before, and I have looked in the FAQ, but I''m
looking for an explanation for the following:

The functions pairs:

gets()/fgets()
puts()/fputs()
printf()/fprintf()
scanf()/fscanf()

differ primarily in that the first one assumes stdin/stdout while the second
one works with a stream passed by the programmer. This makes sense and makes
the functions easy to remember.

But then we have:

getc()/fgetc()
putc()/fputc()
getchar()/fgetchar()
putchar()/fputchar()

In each case the pairs of functions perform the same task. This makes it
hard for people that don''t use these functions all the time because
everytime they use one they have to look up whether it assumes one of the
standard streams or not. Is there a reason that the standard did not adopt a
consistent (and quite useful) naming convention for these functions?


解决方案


"William L. Bahn" <wi*****@toomuchspam.net> wrote in message
news:10*************@corp.supernews.com...

I''m sure this has been asked before, and I have looked in the FAQ, but I''m
looking for an explanation for the following:

The functions pairs:

gets()/fgets()
puts()/fputs()
printf()/fprintf()
scanf()/fscanf()

differ primarily in that the first one assumes stdin/stdout while the second one works with a stream passed by the programmer. This makes sense and makes the functions easy to remember.

But then we have:

getc()/fgetc()
putc()/fputc()
getchar()/fgetchar()
putchar()/fputchar()

In each case the pairs of functions perform the same task. This makes it
hard for people that don''t use these functions all the time because
everytime they use one they have to look up whether it assumes one of the
standard streams or not. Is there a reason that the standard did not adopt a consistent (and quite useful) naming convention for these functions?



Yeah, fgetc() and fputc() make sense, but getc()/putc() should do what
getchar()/putchar() do. It may actually be even less consistant than you''re
saying, though. The arguments for fputs() are backwards from fprintf()
(fprintf() must be that way), the arguments for fputs() and fgets() don''t
match, and the "f" in fgetchar() and fputchar() doesn''t seem to refer to
anything. To (partly) answer your question, the latter two functions are
actually not part of "the standard."


"William L. Bahn" <wi*****@toomuchspam.net> wrote:

The functions pairs:

gets()/fgets()
Don''t use gets(). Ever. It is an irrepairable security hole, because
there is no way to tell it where its buffer stops and it will start to
munge other variable or worse..
puts()/fputs()
printf()/fprintf()
scanf()/fscanf()

differ primarily in that the first one assumes stdin/stdout while the second
one works with a stream passed by the programmer. This makes sense and makes
the functions easy to remember.
That''s deceptive, though. It''s true in the case of (f)printf() and
(f)scanf(), but puts(s) actually does something subtly different from
fputs(s, stdin);
But then we have:

getc()/fgetc()
putc()/fputc()
getchar()/fgetchar()
putchar()/fputchar()
No, we don''t. There is no such thing as fgetchar() and fputchar() in C.
In each case the pairs of functions perform the same task.
No, they don''t. fgetc(instream) gets a character from instream.
getc(instream) does the same thing superficially, but it is allowed to
evaluate its parameter more than once. This means that
fgetc(instream[i++]) is safe, but getc(instream[i++]) is not safe; it
might evaluate i++ more than once, even more than once between two
sequence points, and thus cause undefined behaviour. The other side of
the coin is that getc() could be slightly faster than fgetc().
getchar() is equivalent to getc(stdin). Since stdin does not contain
side effects, this is both safe and efficient.
The same thing is true for fputc()/putc()/putchar()/stdout, with the
proviso that putc() is only allowed to evaluate its second argument more
than once; putc(line[i++], outstream) is safe, but putc(i,
outstream[j++]) is not.
This makes it
hard for people that don''t use these functions all the time because
everytime they use one they have to look up whether it assumes one of the
standard streams or not. Is there a reason that the standard did not adopt a
consistent (and quite useful) naming convention for these functions?



I presume it was for historical reasons; that is, because it was the way
pre-Standard C implementations usually did it, and changing it would
have broken too much existing code.

Richard


In <10*************@corp.supernews.com> "William L. Bahn" <wi*****@toomuchspam.net> writes:

But then we have:

getc()/fgetc()
putc()/fputc()
getchar()/fgetchar()
putchar()/fputchar()

In each case the pairs of functions perform the same task. This makes it
hard for people that don''t use these functions all the time because
everytime they use one they have to look up whether it assumes one of the
standard streams or not. Is there a reason that the standard did not adopt a
consistent (and quite useful) naming convention for these functions?



The naming convention predates the standard, and it is consistent, even if
it is not obvious to those unfamiliar with the language history.

First, there is no such thing as fgetchar and fputchar, so we''re
left only with the getc/fgetc and putc/fputc pairs. The ''f'' stands, in
both cases, for "function", which makes perfect sense once you understand
the history of <stdio.h>.

In the pre-ANSI days, getc and putc were typically implemented as macros,
only. This was good enough for most purposes, unless you needed to pass
their address to another function or, for some other reason, needed a
function with the semantics as these macros. So, fgetc and fputc have
been introduced as the function versions of getc and putc.

Things are different in standard C, because each function in the standard
C library must be implemented as a function, even if it is also provided
as a macro. So, you can take the address of getc, or even call the
function version of getc, if you''re careful enough to bypass the macro.
Likewise, fgetc and fputc can be provided as macros, too, although I can''t
imagine why any implementor might want to do so.

But even today there is a subtle difference between the plain versions and
the f-versions: if implemented as macros, all the functions from the
standard C library are restricted to single evaluation of each of their
parameters. This makes something like putchar(i++) safe: i is guaranteed
to be incremented once, even if putchar is implemented as a macro.
However, there are two exceptions from this rule: getc and putc. If
implemented as macros, they are allowed to evaluate their FILE pointer
parameter (and *only* this parameter) more than once. So, in the
unlikely event that you ever need to call getc/putc with an expression
containing side effects as the FILE pointer argument, use the f-version
instead.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de


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

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