键盘缓冲区残余信息问题
#include <stdio.h>
int main()
{
int a;
char c;
do
{
scanf("%d",&a);
scanf("%c",&c);
printf("a=%d c=%c\n",a,c);
/*printf("c=%d\n",c);*/
}while(c!=''N'');
}
scanf("%c",&c);这句不能正常接收字符,什么原因呢?我们用printf("c=%d\n",c);将C用int表示出来,启用printf("c=%d\n",c);这一句,看看scanf()函数赋给C到底是什么,结果是 c=10 ,ASCII值为10是什么?换行即\n.对了,我们每击打一下"Enter"键,向键盘缓冲区发去一个“回车”(\r),一个“换行"(\n),在这里\r被scanf()函数处理掉了(姑且这么认为吧^_^),而\n被scanf()函数“错误”地赋给了c.
解决办法:可以在两个scanf()函数之后加个fflush(stdin);,还有加getch(); getchar();也可以,但是要视具体scanf()语句加那个,这里就不分析了,读者自己去摸索吧。但是加fflush(stdin);不管什么情况都可行。
函数名: fflush
功 能: 清除一个流
用 法: int fflush(FILE *stream);
#include <stdio.h>
int main()
{
int a;
char c;
do
{
scanf("%d",&a);
fflush(stdin);
scanf("%c",&c);
fflush(stdin);
printf("a=%d c=%c\n",a,c);
}while(c!=''N'');
}
这里再给一个用“空格符”来处理缓冲区残余信息的示例:
运行出错的程序:
#include <stdio.h>
int main()
{
int i;
char j;
for(i = 0;i < 10;i++)
{
scanf("%c",&j);/*这里%前没有空格*/
}
}
使用了空格控制符后:
#include <stdio.h>
int main()
{
int i;
char j;
for(i = 0;i < 10;i++)
{
scanf(" %c",&j);/*注意这里%前有个空格*/
}
}
可以运行看看两个程序有什么不同。
本博客所有内容是原创,如果转载请注明来源
http://blog.csdn.net/myhaspl/
高级版的取子串函数,可以完成正向取子串,反向取子串,
1、调用:
substr(取出的子串,源串,起始位置,长度)
函数返回实际取到子串的长度
其中长度可以为正数(从左边向右边取),长度为负数(从右边向左边取),长度可以超过实际能取到的子串长度,函数会智能判断,取长度范围内尽可能长的子串。
2、函数源代码
C代码
int substr(char* dchr,char *schr,int begin,int len){
//作者:
[email protected]
//取子串函数,dchr为取好后的子串,schr为源串,返回成功取出的子串数目,len为负数,则从begin向头部移动(正向),否则向尾部移动(反向),begin为起始位置(从1开始),len为子串长度
int slen=0;
int rc=0;
if (begin<=0) begin=1;//起始位置为0时,会从1开始
slen=strlen(schr)-begin;
if (slen<=0||len==0){//当len为0或begin的位置已经超过源串长度时,取空串
*dchr=NULL;
return rc;
}
if (len<0){//len为负数,表示从begin处向头部移动len个字符的子串,允许出现len移过头的现象(begin=3,len=-6,则取从位置1到位置3的子串)
len=-len;
if(len>strlen(schr)) begin=1;
else if((begin-len)<=0){
len=begin;
begin=1;
}
else {
begin-=len;
begin++;
}
}
begin--;
schr+=begin;
int i=0;
for(i=0;i<len&&*schr!=0;i++){
*dchr++ = *schr++;
}
*dchr=0;
rc=i;
return rc;
}
c_预定义宏-反映编译信息
1、 __LINE__:被编译的文件中的行号
2、 __FILE__:编译的日期
3、 __DATE__:编译的日期("Mm dd yyyy")
4、 __TIME__:编译的时间("hh:mm:ss")
5、 __STDC__:如果编译器符合C标准(C89或C99),则值为1
C-#line和#error
1、
1)源代码:
test2.c
C代码
#line 1
int main(void){
printf("line 1\n");
printf("line 2\n");
printf("line 3\n");
printf("line 4\n");
printf("line 5\n");
printf("line 6\n");
printf("line 7\n");
printf("line 8\n");
#include "test1.c
test1.c
C代码
#line 9 "test2.c"
#define LINUX
#ifdef WIN32
printf("win32\n");
#elif defined LINUX
printf("linux %d %s\n",__LINE__,__FILE__);
#else
#error no flag define
//如果LINUX和WIN32没有定义,#error会显示错误信息,然后停止编译
#endif
}
2)运行结果:
mysea@mysea-pc:~/test$ ./test2
line 1
line 2
line 3
line 4
line 5
line 6
line 7
line 8
linux 13 test2.c
2、#error表示停止编译,显示错误信息
3、#line 直接指定下一行的行号及文件名
1)指定行号
#line n
2)指定文件名和行号
#line n "filename"
4、源代码的#include "test1.c"和#line 9 "test2.c"表示:test2.c和test1.c实质属于一个C程序:test2。
1)注意这只是标注,如果要在编译时把test1.c包括进来,必须加上#include "test1.c
2)编译时,编译test2
mysea@mysea-pc:~/test$ gcc -o test2 test2.c