在getchar函数/龟etc和的putchar / INT的fputc和char的区别?
我想学习C我自己,我是那种与的getchar
的困惑和的putchar
:
I am trying to learn C on my own and I'm kind of confused with getchar
and putchar
:
#include <stdio.h>
int main(void)
{
char c;
printf("Enter characters : ");
while((c = getchar()) != EOF){
putchar(c);
}
return 0;
}
2
#include <stdio.h>
int main(void)
{
int c;
printf("Enter characters : ");
while((c = getchar()) != EOF){
putchar(c);
}
return 0;
}
C库函数 INT的putchar(INT C)
写入由参数字符到stdout指定的字符(unsigned char类型)。
The C library function int putchar(int c)
writes a character (an unsigned char) specified by the argument char to stdout.
C库函数 INT的getchar(无效)
获取从标准输入一个字符(unsigned char类型)。这相当于是:标准输入作为其参数GETC。
The C library function int getchar(void)
gets a character (an unsigned char) from stdin. This is equivalent to getc with stdin as its argument.
这是否意味着的putchar()
同时接受 INT
和字符
或其中之一,并为的getchar()
我们应该使用 INT
或焦
?
Does it mean putchar()
accepts both int
and char
or either of them and for getchar()
should we use an int
or char
?
TL; DR:
-
字符℃; C =的getchar();
为错了,坏了,车 -
INT℃; C =的getchar();
为正确
-
char c; c = getchar();
is wrong, broken and buggy. -
int c; c = getchar();
is correct.
这适用于 GETC
和龟etc
还有,如果更加并非如此,因为你希望总是得到一个 EOF
读取文件时。
This applies to getc
and fgetc
as well, if not even more so, because you'd expect to always get an EOF
when reading a file.
总是存储的getchar
的返回值(龟etc
, GETC
...)(和的putchar
)开始到类型的变量 INT
。
在参数以的putchar
可以是任何 INT
,的char
,符号字符
或 unsigned char型
;它的类型并不重要,和他们都工作相同,即使一个可能导致以正和负整数其他传递上面,并包括 \\ 200
字符( 128)。
Always store the return value of getchar
(fgetc
, getc
...) (and putchar
) initially into a variable of type int
.
The argument to putchar
can be any of int
, char
, signed char
or unsigned char
; its type doesn't matter, and all of them work the same, even though one might result in positive and other in negative integers being passed for characters above and including \200
(128).
为什么你的原因必须使用 INT
来存储的返回值 的getchar
和的putchar
是当达到 EOF
情况下,它们都返回宏 EOF
这是一个负的整型常量和(通常) 1
;如果返回值不是 EOF
,它是读的无符号字符的零扩展为整数。也就是说,假设8位字符,返回可值 0
... 255
或特殊的宏 EOF
;再次假定8位字符,没有办法去挤这257不同的值到256。
The reason why you must use int
to store the return value of both getchar
and putchar
is that when EOF
condition is reached, both of them return the macro EOF
which is a negative integer constant, and (usually) -1
; if the return value is not EOF
, it is the read unsigned character zero-extended to an integer. That is, assuming 8-bit characters, the values returned can be 0
...255
or the special macro EOF
; again assuming 8-bit char, there is no way to squeeze these 257 distinct values into 256.
现在,如果你把它存储到字符
代替,效果将取决于是否的字符类型是有符号或默认符号!这种由不同的编译器编译器,架构架构。如果字符
签订并假设 EOF
定义为 1
和两个 EOF
和字符'\\ 377'
上的投入将比较等于 EOF
;他们会被符号扩展为(INT)-1
。
Now, if you stored it into char
instead, the effect would depend on whether the character type is signed or unsigned by default! This varies from compiler to compiler, architecture to architecture. If char
is signed and assuming EOF
is defined as -1
, then both EOF
and character '\377'
on input would compare equal to EOF
; they'd be sign-extended to (int)-1
.
在另一方面,如果字符
是无符号的,还有的可能被存储在 C 的值/ code>将比较等于
1
;包括 EOF
;而不是打破了上 EOF
,您的code将输出一个 \\ 377
字符。
On the other hand, if char
is unsigned, there is no value that could be stored in c
that would compare equal to -1
; including EOF
; instead of breaking out on EOF
, your code would output a single \377
character.
这里的危险在于,与签署字符
S中的code的似乎是正确的,即使它是仍在工作可怕的破 - 合法的输入值之一是PTED为 EOF
间$ p $ 此外,C89,C99,C11并不强制为 EOF ;它只是说 EOF
是负的整型常量;从而代替 1
它可以同时是说 -224
在一个特定的实现,这将导致空间表现得像 EOF
。
The danger here is that with signed char
s the code seems to be working correctly even though it is still horribly broken - one of the legal input values is interpreted as EOF
. Furthermore, C89, C99, C11 does not mandate a value for EOF
; it only says that EOF
is a negative integer constant; thus instead of -1
it could as well be say -224
on a particular implementation, which would cause spaces behave like EOF
.
GCC
具有可用于使开关 -funsigned-CHAR
的焦
符号在这些平台上它默认为签署
gcc
has the switch -funsigned-char
which can be used to make the char
unsigned on those platforms where it defaults to signed:
% cat test.c
#include <stdio.h>
int main(void)
{
char c;
printf("Enter characters : ");
while((c= getchar()) != EOF){
putchar(c);
}
return 0;
}
现在,我们与运行它签署字符
:
Now we run it with signed char
:
% gcc test.c && ./a.out
Enter characters : sfdasadfdsaf
sfdasadfdsaf
^D
%
似乎是工作的权利。但随着无符号字符
:
% gcc test.c -funsigned-char && ./a.out
Enter characters : Hello world
Hello world
���������������������������^C
%
这就是我试图preSS 按Ctrl-D
有很多次,但一个
印刷每个 EOF
而不是打破循环。
That is, I tried to press Ctrl-D
there many times but a �
was printed for each EOF
instead of breaking the loop.
现在,再次为签署字符
的情况下,它不能字符
255 EOF 在Linux上,打破它的二进制数据和这样的:
Now, again, for the signed char
case, it cannot distinguish between char
255 and EOF
on Linux, breaking it for binary data and such:
% gcc test.c && echo -e 'Hello world\0377And some more' | ./a.out
Enter characters : Hello world
%
只有第一部分到 \\ 0377
逃脱被写入stdout。
Only the first part up to the \0377
escape was written to stdout.
要注意的是字符常量和 INT
包含无符号字符值可能无法按预期工作(如字符常量',以'在ISO 8859-1将意味着符号值
-28
,所以假设你写code,将读取输入直到在ISO 8859-1 codePAGE',以'
,你会做
Beware that comparisons between character constants and an int
containing the unsigned character value might not work as expected (e.g. the character constant 'ä'
in ISO 8859-1 would mean the signed value -28
. So assuming that you write code that would read input until 'ä'
in ISO 8859-1 codepage, you'd do
int c;
while((c = getchar()) != EOF){
if (c == (unsigned char)'ä') {
/* ... */
}
}
由于整型提升,所有的字符
价值观匹配到 INT
,并自动在函数调用提升,因此,你可以给任何 INT
,字符
,的符号字符
或 unsigned char型
到的putchar
为参数(而不是存储它的返回值) ,它会正常工作。
Due to integer promotion, all char
values fit into an int
, and are automatically promoted on function calls, thus you can give any of int
, char
, signed char
or unsigned char
to putchar
as an argument (not to store its return value), and it would work as expected.
在整数传递的实际值可能是正的或甚至负的;例如字符常量 \\ 377
是负的一个8位字符的系统上,其中字符
签署;然而的putchar
(或的fputc
实际上)将值转换为unsigned char类型。
The actual value passed in the integer might be positive or even negative; for example the character constant \377
would be negative on a 8-bit-char system where char
is signed; however putchar
(or fputc
actually) will cast the value to an unsigned char.