我自己已经建立好了test.txt文件夹,
并写了一些内容):
[cpp]
view
plain
copy
#include
<stdio.h>
int
main()
{
char
c
FILE
*fp
=
fopen("test.txt",
"r")
if(NULL
==
fp)
{
return
1
}
while(EOF
!=
(c
=
fgetc(fp)))
{
putchar(c)
}
fclose(fp)
printf("\n")
return
0
}
在VC++6.0中运行的结果是:
abcdefg
看起来没有问题,
那么在其他系统中运行呢?厅竖棚
我试了几个环境,
发现都是OK的,
但是,
上面程序是有问题的。
先从逻辑上来说吧,
在正常情况下,
因此正常情况下用char
c中的c去存这个返回的值,
是足够的。
但是,
当已经达到文件尾或者fgetc函数出错的时候,
就会返回一个错误值,
那怎么去存错误值呢?
显然c的范围必须必char的范围要大才可,
所以用char
c是不正确的。
从实际上来说,
我们知道,
在大多数系统中char被默认为signed
char,
所谓范围是-128-127.
所以,
如果已经达到文件尾或者fgetc函数出错,
则会返回-1,
而EOF的值也通常是-1,
所以,
在上面的程序中,
while循环可以顺利退出。
但是,
在有的系统中,
char被默认为unsigned
char,
此时,
如果fgetc函数返回-1,
一旦赋值给c后,
c就是个正值了,
于是上面的while陷入了死循环。因此,
应该用int
c来存-1.
要说明的是,
在所有系统中,
int被默认为signed
int,
但char却比较特别,
不一定是signed
char,
尽管绝大多是时候是。(这一论断在《C++编程思想》的第一卷中有介绍,
请参考第三章"C++中的C"中的叙述)
可见,
为了程序的可移植性,
应该用int
c
其实扮则,
你看看,
fgetc的原型中,
返回值的类型就是int.
“我的疑惑”:我们再来仔细思考一下,
比如在VC++6.0中,
改为int
c后就不会有问题吗?
我把char形的-1写入到文件中,
读取的也是-1,
那岂不是错判为“fgetc函数遇到了文件尾纤笑或者出错”了?
那while循环岂不是不正确地结束了?
带着这些疑问,
我们先来看看下面这个简单的程序
[cpp]
view
plain
copy
#include
<stdio.h>
int
main()
{
FILE
*fp
=
fopen("test.txt",
"w")
if(NULL
==
fp)
{
return
1
}
char
ch
=
-1
fputc(ch,
fp)
//
实际上fputc的原型要求ch为int,
不过不影响我做测试,
因为char在VC++6.0中的范围是-128-127.
fclose(fp)
int
c
fp
=
fopen("test.txt",
"r")
if(NULL
==
fp)
{
return
1
}
c
=
fgetc(fp)
printf("%d",
c)
//
是255,
而不是-1哈
fclose(fp)
printf("\n")
return
0
}
上述结果中,
c的值是255,
而不是-1,
这就说明,
在正常情况下,
fgetc从文件中读出的不可能是负值,
因为ascii值不可能是负值。
而我们知道,
一旦达到文件尾或者fgetc函数出错,
会返回-1,
可见,
正确的值和错误的值是完全区分开了的。
进而可知,
上面“我的疑惑”不再疑惑。
我们再来反思一下,
char
c
c
=
fgetc(fp)在VC++6.0中真的不存在问题吗?上菜:
[cpp]
view
plain
copy
#include
<stdio.h>
int
main()
{
FILE
*fp
=
fopen("test.txt",
"w")
if(NULL
==
fp)
{
return
1
}
fputc(128,
fp)
fclose(fp)
char
c
fp
=
fopen("test.txt",
"r")
if(NULL
==
fp)
{
return
1
}
c
=
fgetc(fp)
printf("%d",
c)
//
是-128,
而不是128哈,
所以即使在VC++6.0中,char
c也是错误的
fclose(fp)
printf("\n")
return
0
}
综上所述:
必须用int
c
,
而类似的函数还有getc,
getchar.
希望大家在以后的笔试面试中注意这点,
在实际项目中也多加注意。最后强调一句,
char可以为负,
但ascii值却没有负值
char *sgets(s)上面这种写法是错误的.s定义成指针,需要有明确的冲晌指向.gets()函数是要求提供具体指针地址,从那个地址开始存储字符串,而如果简单定义char *ss是个野指针散数锋,无法提供具体指向。可以修改毕厅
成char *schar a[100]s=agets(s)这样让s指向数组a,确定地址方位。
char *ss="ABCDEF"
上面这种写法是可以的.让s指向字符串常量首地址。可以进行打印 *** 作puts(s)但不能进行修改 *** 作*s='a'因为常量字符串的限制。
建议你上机运行下这几句,编译都能通过.不过,执行时候,看看效果
不正确。x[4]也就是 *(x+4),是字符‘g',不能将一隐物个字符赋值给字灶慧液符串。但可以这样写:strcpy(y,x+4),即碧盯,将"ghi"赋值给y字符串。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)