blog date : 2015-12-19
对于C/C++语言相关的知识目前借助的是《C语言大学教程》这本书,后面就是零散的记录一些知识和问题,如果有大块的内容再做系统的分析和记录。
1,对于#define的认识,#define是程序编译时预处理的步骤,这时候还没有进入正式编译,对于#define来讲他的行为是进行文本的替换,也就是说在后续编译的时候将define的宏文本进行替换然后进行编译,这也就是为什么在#define后加分号时,会报语句不完整的错误,因为相当于在代码中间多了一个分号;
2,关于scanf和键盘缓冲区的问题,这个可能写的会稍微长一些。
scanf在C中不能输入空格、TAB、换行、EOF等字符,在输入这些字符之后会退出函数,那么如果要用scanf支持空格输入怎么办呢,我在网上找到了一个办法是scanf("%[^\n]",str),这里用到了一个类似正则表达式的东西^,表示如果不接受\n,那么在敲入回车之后才会退出scanf函数,于是我写了下面这个小程序来验证:
int main()
{
char string1[100];
while(1){
scanf("%[^\n]",string1);
printf("%s\n",string1);
}
return 0;
}
这时候就出现了问题,在第一次输入"hello world"之后,后面就开始被hello world刷屏了,这应该是键盘缓冲区的问题,如果用fflush(stdin);或者rewind(stdin);清除键盘缓冲区就可以解决这个问题,每次输入、然后printf输入字符串后,可以进行下一次键盘输入。但是到底键盘缓冲区出了什么问题我很好奇,于是我做了如下的测试:
int main()
{
char string1[100];
char str;
int temp;
while(1){
//rewind(stdin);
//fflush(stdin);
temp = scanf("%[^\n]",string1);
str = getchar();
printf("%s\n",string1);
}
return 0;
}
发现scanf之后getchar是一个换行符,而如果没有这个getchar循环的第二次以后temp都是0,意味着键盘缓冲区在第一次scanf之后留下了一个\n,这个在下一次循环scanf的时候遇到\n停止认为什么都没读到,然后继续。这说明用scanf("%[^\n]",str)最后的\n不会像scanf("%s",str)那样把空格、换行清掉。
对于这个问题还可以用如下方式解决scanf("%[^\n]%*c",str),%*c相当于忽略后面的字符,这时候就会把\n清掉,键盘缓冲区就不再有其他无用字符了。感觉这个scanf和getchar还是有关系的,不知道是不是scanf就是用getchar实现的,这也算一个小bug吧。这表明在使用键盘输入的时候还是要多做清除键盘缓冲区的处理,这样可以保证程序的健壮性和安全性。