问题1:将两个变量的数据类型相互交换后,没有得到想要的结果。
结论:对于%c的scanf,要么scanf(" %c",…),要么在之前加上while((c = getchar()) != ‘\n’);
之前的代码和显示结果如下:
其中name的数据类型是char,pwd的数据类型是int。
然后我将两个变量的数据类型调换位置,即name的数据类型变成int,pwd的数据类型变成char,后面与变量对应的转义字符也改变。
之后的代码和结果显示如下:
char name;
int pwd;
printf("请输入用户名:");
scanf("%d",&name);
printf("请输入密码:");
scanf("%c",&pwd);
printf("用户名是%d,密码是%c",name,pwd);
解决方法1:只需要在scanf("%c",&name);里面的%c前面加上一个空格即可。(不用在%d前面加空格)
解决后的代码和结果如下:
char name;
int pwd;
printf("请输入用户名:");
scanf("%d",&name);
printf("请输入密码:");
scanf(" %c",&pwd); //加了空格
printf("用户名是%d,密码是%c",name,pwd);
解决方法2:在第一个scanf和第二个scanf之间加上一行代码
while((c = getchar()) != '\n');
即可
解决后的代码和结果如下:
char name;
int pwd,c;
printf("请输入用户名:");
scanf("%d",&name);
while((c = getchar()) != '\n');
printf("请输入密码:");
scanf("%c",&pwd);
printf("用户名是%d,密码是%c",name,pwd);
2019年2月18日22:30分,我人生中第一个从构思到打代码到实现、完全自主的代码终于成功了。
我们知道在printf中若要引用,需要在字符串后面用逗号隔开并列出要引用的内容。在打代码的时候我便注意到这里的c d e f并不需要加上双引号,但之前有条代码是加了双引号的
经过我的回忆和比较,我便得出:在printf中若是引用数字或者变量,不用加双引号;若是引用字符或者字符串,就要加上双引号。
问题2 scanf的“小心机”
笔者最近做了一个打怪兽的“小游戏”,最初的正确代码如下:
编译结果如下:
但是,由于“攻击值”对应的变量是char,所以再输入“攻击值”时,一旦输入的数字超出个位数,则会出现下面这种结果:
“攻击值”输入12,按下回车键立马让你输入恢复值。
注意:我当时还没有注意到这点,因为char在输入时可以这样:char a = 100,等号后面的数字从-128到127都可以,但是在其他输入方式尤其是要引用%c的时候,就只能输入“字符”即单个数字或字母。
在没有注意到这一点时,我对代码进行了改进,改进结果如下:
我加入了“暂停”,就不会一下子跳到恢复值了,编译结果如下:
啊哈,我当时想,这下终于对了。但是拿出计算器手动计算时,我发现最终算出的生命值不对!其实这条代码仍然是正确的,它的echo %errorlevel%为零。这是我才反应过来,我试了下只输入个位数,最终的编译结果才变正确的。
所以,上面这个编译结果,其实是错误的!编译器在计算时,由于攻击值只能输入个位数,所以这里的攻击值其实不是12!
问题:str(len)喜欢fgets的回车符
在学到字符数组的时候,我学到了三种输入方法:scanf gets fgets。scanf遇到空格就会停止输入,其他两种则不会。然而gets fgets两者在某些情况下表现得也不一样。
1.喜欢回车键的fget
使用fgets输入:
char name[32];
int len;
printf("请输入姓名:");
fgets(name,5,stdin);
len = strlen(name);
printf("字符串的长度为%d", len);
scanf gets fgets都有输入缓冲区,回车键也会在输入缓冲区中。一串字符串包括:字符串+休止符+回车符 。字符长度是指字符串的长度。但是一旦fgets与str(len)相配,str(len)就会把输入缓冲区的回车符也包括进字符串长度里。
使用gets输入:
char name[32];
int len;
printf("请输入姓名:");
gets(name);
len = strlen(name);
printf("字符串的长度为%d", len);
而gets与str(len)相配,str(len)就不会把回车符当做字符串长度了。
与字符串长度strlen相关的,还有个字符串的比较,strcmp。strcmp将两个字符串的a[0] a[1]根据其对应的ASC数值依次比较。但是strcmp一旦与fgets相遇,也会出现差错。
char str1[32];
char str2[32] = "Rock";
fgets(str1,sizeof(str1),stdin);
printf("数值是%d", strcmp(str1,str2));
return 0 ;
sizeof(str1)在这里等于32,若我输入一个“Rock”则只有5个字符远小于32,那么此时fgets就会把回车符也包括进去,一共就有6个字符。
str1的输入缓冲区包含:‘R’ ‘o’ ‘c’ ‘k’ 0 ‘\n’
str2的输入缓冲区包含:‘R’ ‘o’ ‘c’ ‘k’ 0
由于’\n’也有对应的·ASC数值,所以编译结果为str1>str2,结果小于0。
总结起来就是:strcmp比较字符串有条规律,就是除去0 ‘\n’的情况下先依次比较ASC数值。若前面的字符串一模一样,则看后面有没有0或者’\n’
问题:字符getchar putchar与scanf printf的区别
char a;
scanf("%d",&a);
printf("%d",a);
return 0;
输入100,输出100
char a;
a = getchar();
printf("%d",a);
return 0;
输入100,输出49
char a;
scanf("%d",&a);
putchar(a);
return 0;
输入100,输出d
char a;
a = getchar();
putchar(a);
return 0;
输入100,输出1
总而言之:对于putchar putc(stdin) 而言,它们都只管字符,并且这里的字符可以理解为“图像”。比如我输入一个“1”其实并不是输入了一个“数字1”,而是一个“图像1”,而这个“图像1”在ASC数表里对应着一个数字。
同样对于getchar getc(stdin)而言,它们也只管字符。
目前学到的可以直接引用不用申明变量的有:strlen() strcmp( , ) sizeof() 所有字符串比较的运算比如30>5 20!=30等都可以直接引用不用申明。
#include <stdio.h>
#include <stdbool.h>
int main(void){
printf("%d\n",3 > 5);
printf("%d\n",30 > 5);
if(true){
printf("真");
}
if(false){
printf("假");
}
return 0;
}
就可以像上面这样,就不用再申明一个比如"int len; len = 3 > 5;"之类的了。