getchar的返回值
这样的代码有什么问题:
char c;
while((c = getchar()) != EOF)....
getchar返回值变量必须是int型。因为EOF通常定义为-1,二十进制为255的字符会被符号扩展,和EOF比较时会相等,从而
过早第结束输入。
feof函数的使用
为什么这些代码最后一行复制了两遍?
- #include <stdio.h>
- #include <unistd.h>
- #include <fcntl.h>
-
- #define MAXLINE 256
-
- int main(void)
- {
- char buf[MAXLINE];
- FILE* fp = fopen("1.txt","r");
- while(!feof(fp)){
- fgets(buf,MAXLINE,fp);
- printf("%s",buf);
- }
- return 0;
- }
在c语言中只有输入例程试图读取并失败以后才能得到EOF,也就是说fgets读到最后一行内容,此时调用feof时,feof并
不能返回非零值(即检测不到EOF),while循环继续执行,fgets执行后,返回值为NULL,但是buf还是上次读取的内容,
所以此时printf再次打印了最后一行内容。等到再次执行feof时,此时feof函数检测到EOF,跳出while循环。
所以我们的可以修改成一下来避免上述的问题:
if(fgets(buf, MAXLINE, fp) != NULL){
printf("%s",buf);
}
其实feof函数都是在fgets失败以后才使用的,应为该函数出错还是出错还是达到文件结尾都返回NULL,为了
区分这两种情况,必须调用ferror或者feof函数。
有人说不能在printf中使用%lf,为什么printf中用%f输出double型,而scanf却用%lf呢?
printf的%f说明符既可以输出float型又可以输出double型。根据默认参数提升规则,float型会被提升为double型,因此
printf只会看到双精度数。
独有scanf,情况就完全不一样了,它接收指针,这里没有类似的类型提升,向float存储和向double存储大小不一样,因此
scanf区分%f和%lf。
对于size_t那样的类型定义,到底是long还是其他类型,应该使用什么样的prinf格式?
把那个值转换为一个已知长度够大的类型,然后使用与之对应的printf格式,例如输出某种类型的长度,可以使用:
- printf("%lu", (unsigned long)sizeof(thetype));
怎样从特定格式的字符串中读取数据?
可以使用sscanf,例如123ABC5.678,可以用”%d%3s%f“读取。
- #include <stdio.h>
-
- int main(void)
- {
- char str[] = "1234ABC5.678";
- int i;
- float f;
- char s[10];
- sscanf(str,"%d%3s%f",&i,s,&f);
- printf("%d,%s,%f\n",i,s,f);
- return 0;
- }
运行结果:
1234,ABC,5.678000
用"%d\n"调用scanf的问题
下面的代码:
- int n;
- scanf("%d\n",&n);
- printf("%d\n",n);
为什么要多输入一行才返回,为什么?
\n在scanf格式中不表示等待换行符,而是读取并放弃连续的空白字符。因此”%d\n“中的\n会让scanf读到非空白字符为止,
而它可能需要读到下一行才能找到这个非空白字符。应该去掉\n,仅适用%d即可。
scanf和gets一起用的副作用
- int n;
- char str[80];
-
- scanf("%d",&n);
- gets(str);
- printf("%d,%s\n",n, str);
以上的代码,好像编译器跳过了gets的调用。
如果你向问题中的程序输入两行:
42
a string
scanf会读取42,但却不会读到紧接其后的换行符,换行符会保留在输入流中,然后被gets读取,后者会读取一个空行,二
第二行的字符串根本不会被读取。