fscanf(scanf)|fgets(fgetchar)函数对于空格和回车的不同处理重 fgets和fscanf

有一道编程如下:

#include <stdio.h>

main()

{int i,flag;

char str[80],c;

FILE *fp;

fp=fopen("text","w");

flag=1;

while(flag==1)

{printf("nInput string:n");

gets(str);

fprintf(fp,"%s",str);

printf("nContinue?");

c=getchar();

if((c=='N')||(c=='n'))

flag=0;

getchar(); (接收回车)

}

fclose(fp);

fp=fopen("text","r");

while(fscanf(fp,"%s",str)!=EOF)

{for(i=0;str[i]!='';i++)

if((str[i]>='a')&&(str[i]<='z'))

str[i]-=32;

printf("n%sn",str);

}

fclose(fp);

}

运行程序时,如果输入“ABC”回车,再输入“DEF”回车,会显示结果“ABCDEF”,但是如果输入的字符串中包含空格,比如输入I AM A STUDENT,结果会将"I" "AM" "A" "STUDENT"这4个字符串分别输出4行上.

要弄清楚这个问题,首先要对fscanf和fgets这两个文件函数的概念有深入的了解,对于字符串输入而言这两个函数有一个典型的区别是:

fscanf读到空格或者回车时会结束并返回,字符串自动加‘’,但是而fgets函数则把空格作为字符接收。

有这样一个例子:

char str[13];

scanf("%s",str);

如果输入以下12个字符How are you?回车

实际上并不是把这12个字符加上送到数组str中,而只将空格前的“How”送到str中,由于把“How”作为一个字符串处理,因此在其后加。

当你敲回车时,实际输入了两个字符,回车(13)和换行(10),scanf遇到回车就返回,结果把一个换行符丢在了键盘缓冲里,而getchar偏偏见了换行符就直接返回,所以没有别的办法,在getchar前面先把输入缓冲清掉,即fflush(stdin),&<60; 如果对输入流内的数据需要保留也可在scanf后面加一句getchar把换行符先读掉,具体情况具体处理。

getchar,gets,见了换行符才返回,所以缓冲区没有回车或者换行这样的字符存在了,因此gets后面的getchar能得到正确的字符,实际上SCANF的这种设计是存在一些问题的,所以才导致这些问题的出现。

我们可以将gets改为scanf,即:

#include <stdio.h>

main()

{int i,flag;

char str[80],c;

FILE *fp;

fp=fopen("text","w");

flag=1;

while(flag==1)

{printf("nInput string:n");

scanf("%s",str);

fprintf(fp,"%s",str);

printf("nContinue?");

c=getchar();

if((c=='N')||(c=='n'))

flag=0;

getchar();

}

fclose(fp);

fp=fopen("text","r");

while(fscanf(fp,"%s",str)!=EOF)

{for(i=0;str[i]!='';i++)

if((str[i]>='a')&&(str[i]<='z'))

str[i]-=32;

printf("n%sn",str);

}

fclose(fp);

}

fscanf(scanf)|fgets(fgetchar)函数对于空格和回车的不同处理(重 fgets和fscanf
这时候我们会发现,即便我们输入n,程序依然会进行下去,原因就是scanf遇到回车符返回了,留有换行符,而第一个getchar遇到换行符返回,读入的数据实际上被第二个getchar所接收了,因此无法结束。

补充一个问题,如果想让"I" "AM" "A" "STUDENT"输出在同一行上程序应该怎么改?

答案就是:fscanf换成fgets(fp, str) 。

再举一例getchar()函数对空格以及回车的处理:

#include<stdio.h>

#define MAX 1000

main()

{int c,i,flag,flag1;

char t[MAX];

i=0;

flag=0;

flag1=1;

printf("nPlease input a hexadecimal number:");

while((c=getchar())!=''&&i<MAX&&flag1)

{if(c>='0'&&c<='9'||c>='a'&&c<='f'||c>='A'&&c<='F')

{flag=1;

t[i++]=c;

}

else if(flag)

{t[i]='';

printf("n decimal number :%dn",htoi(t));

printf("continue? (Y/N):");

c=getchar();

if(c=='N'||c=='n')flag1=0;

else

{flag=0;

i=0;

printf("nPlease input a hexadecimal number:");

}

}

}

}

htoi(s)

char s[];

{int i,n;

n=0;

for(i=0;s[i]!='';i++)

{if(s[i]>='0'&&s[i]<='9')n=n*16+s[i]-'0';

if(s[i]>='a'&&s[i]<='f')n=n*16+s[i]-'a'+10;

if(s[i]>='A'&&s[i]<='F')n=n*16+s[i]-'A'+10;

}

return(n);

这道编程表面上看起来没什么,实际有一些玄妙:

第一次运行:Please input a hexadecimal number:

输入:12 回车

decimal number :18

continue? (Y/N):y

Please input a hexadecimal number:

这时如果输入:AC空格 回车

会出现这样的结果:

decimal number:172

continue? (Y/N):

Please input a hexadecimal number:

也就是直接跳过continue? (Y/N):的条件判断了,这不得不让人很是奇怪,怎么会不让我输入“Y”或“N”来判断呢?那么我上面输入:12 回车,怎么就需要判断了呢?

其实这个问题也和上面的类似,输入AC+空格后,getchar函数已经得到了空格,并且这个空格在随后的语句中没有得到处理,不同于AC已经在if语句中被处理t[i++]=c;那么在continue? (Y/N):这个条件判断中,内存中还保留有空格,所以不进行输入(Y/N)判断而直接继续后面的语句。

同样你输入ACZ这样的字符串也不会进行判断,这时内存中存储的是Z,这里以回车和空格举例只是为了说明两者之间的区别。

  

爱华网本文地址 » http://www.413yy.cn/a/25101011/60713.html

更多阅读

白葡萄酒和红葡萄酒的区别及功效 白葡萄酒和香槟的区别

1、葡萄酒的营养作用葡萄酒是具有多种营养成分的高级饮料。适度饮用葡萄酒能直接对人体的神经系统产生作用,提高肌肉的张度。除此之外,葡萄酒中含有的多种氨基酸、矿物质和维生素等,能直接被人体吸收。因此葡萄酒能对维持和调节人体的

长方体和正方体的表面积教学反思 体积和容积的意义反思

《长方体和正方体的表面积》是在学生认识并掌握了长方体、正方体特征的基础上教学的,也是学生学习几何知识由平面计算扩展到立体计算的开始,是本单元的重要内容。学生对旧知识已经有了一定的积累,但空间思维还没有真正形成。为了使学生

李白和他的山水诗 山水诗和田园诗的区别

李白和他的山水诗郭 宇(人文学院 B06中文1班学号:060701150)【摘要】李白,盛唐最杰出的诗人,也是我国文学史上继屈原之后又一伟大的浪漫主义诗人,素有“诗仙”之称。他经历坎坷,思想复杂,既是一个天才的诗人,又兼

声明:《fscanf(scanf)|fgets(fgetchar)函数对于空格和回车的不同处理重 fgets和fscanf》为网友自作多情的人分享!如侵犯到您的合法权益请联系我们删除