第三次作业
一.代码练习
1.
int main()
{
int num;
for (num=1;num<=11;num++)
{
if(num%3==0)
putchar('$');
else
putchar('*');
putchar('#');
putchar('%');
}
putchar('\n');
return 0;
}
运行结果如图
if else语句包括在for循环中,else语句后面有3个putchar输出函数,但是只有第一个putchar()才能参与else判断,除非else用花括号将3个输出函数括起来。
2.switch函数的运用
int main()
{
int i=0;
while (i<3)
{
switch (i++)
{
case 0:printf("fat");
case 1:printf("hat”);
case 2:printf("cat");
default:printf("Oh no!");
}
putchar('\n');
}
return 0;
}
运行结果如图
此代码中未有break来结束循环从而程序会一直按顺序运行下去。 如果在case2后加一个break
i=1时case2:后面的语句都直接停止了但i=3时switch直接定位到case3直接运行下面的程序
3.错误代码
int main()
{
int age=20;
while (age++ <=65)
{
if((age%20)==0)
printf("%d\n",age);
if(age=65)
printf("%d\n",age);
}
return 0;
}
如图
在第二个if语句中的age=65,不断把65赋值给这是if语句判断为从而不断控制输出65,由此看出age=65是把65赋值给age,而age==65是age等于65,两者意义不同。
3.
int main()
{
char ch;
int num;
num=1;
while ((ch=getchar())!='#')
{
printf("%4c is %1d",ch,ch);
if ((num++%8)==0)
printf("\n");
}
return 0;
}
题目要求打印输入的每个字符及其ASCII码,并要求每行打印8个字符-ASCII码之后打印一个换行符,可以用到求模运算符来确定什么时候打印。注意num%8时num初始值等于0时一开始也会num%8的值也是0.
运行结果如图
4.
int main()
{
int shu,num,opj,jpj,jishu,oushu,jnum,onum;
num;
jishu=0;
oushu=0;
jnum=0;
onum=0;
while (scanf("%d",&shu)==1)
{
if (shu==0)
break;
else if ((shu%2)==0)
{
printf("偶数%d\n",shu);
oushu+=shu;
onum++;
}
else
{
printf("奇数%d\n",shu);
jishu+=shu;
jnum++;
}
}
printf("cishu%d %d\n",onum,jnum);
opj=oushu/onum;
jpj=jishu/jnum;
printf("pingjun%4d %4d\n",opj,jpj);
return 0;
}
运行结果如图
当不加入shu=0时循环结束,要循环结束必须输入一个字符来使scanf的返回值为0,但加入一个break函数来结束循环的话就特别方便。第一眼看去以为循环条件应该这样设立while(scanf(“%d”,&shu)!=0)但scanf返回的只有0和1所以,必须在循环内设一个代码来再结束循环。
5.
int main()
{
int a,b,c;
char ch;
a=0;
b=0;
while ((ch=getchar())!='#')
{
if (ch=='.')
{
ch='!';
a++;
}
else if (ch=='!')
{ ch='!!';
b++;
}
}
c=a+b;
printf("%d",c);
return 0;
}
题目要求计算替换次数,且要求读到#时停止,每读取的一个字符进行一次循环,虽然输入的字符发生了改变但a与b的值并没有被初始化。
运行结果如图
如果运用switch来重新上面程序。
int main()
{
int a,b,c;
char ch;
a=0;
b=0;
printf("请输入:\n");
while ((ch=getchar())!='#')
{
switch(ch)
{
case '.':
ch='!';
a++;
continue;
case '!':
ch='!!';
b++;
continue;
}
}
c=a+b;
printf("%d",c);
return 0;
}
改用switch的话根据case的标签来判别'.'和'!',但判别后必须使其退出循环,所有需要一个continue来使程序退出循环,重新开始检查下一个字符。
6.如何检查一段话中某一个单词出现的次数?
int main()
{
int cishu;
int panduan;
char ch;
cishu=0;
while ((ch=getchar())!='#')
{
switch(ch)
{
case 'e':
panduan=1;
break;
case 'i':
if (panduan==1)
{
cishu++;
panduan=0;
}
break;
default :
panduan=0;
}
}
printf("次数%d\n",cishu);
return 0;
}
想要判断一段字符中含有多少个ei,首先肯定先判断e然后再判断下一个字符是否为i,但可能识别i时要有一个标准来证明前一个字符为e,所以对panduan进行赋值当识别到e时赋值1给它,当检查i时就以panduan=1作为判断标准。最后以break结束循环。但要对panduan重新赋值使其赋一个不等于1的值。
二.字符输入/输出和输入验证
1.缓冲区
| 无缓冲输入 | 缓冲输入 |
|---|---|
| 回显示用户输入后的字符立即重复打印该字符 | 包括:完全缓冲I/O,行缓冲I/O |
- 完全缓冲:当缓冲去被填满时才刷新缓冲区。
- 行缓冲:出现换行符时刷新缓冲区。键盘输入通常是行缓冲输入,按下Enter键刷新
2.文件结尾
一般来说是在文件末尾放一个特殊字符标记文件末尾如:ctrl+z.另一种就是储存文件大小信息。
3.getchar(),scanf(),检测到文件结尾返回EOF
EOF的值stdio.h文件中把EOF通常定义为-1,因为比如getchar的返回值可能处于0-255之间(返回字母时在0-127之间,但也可以返回一些如:*,&,%的符号
int main()
{
int ch;
while ((ch=getchar())!='EOF')
putchar(ch);
return 0;
}
如上代码
注意:
1.一开始把ch定义为整形,所有getchar给他返回的数也是整形。
2.无需定义EOF因为在头文件中以定义。
3.无需赋值EOF,因为在stdio.h文件中已经用#define定义了EOF。
4.putchar(ch)虽然是数字但putchar任然会打印等价的字符。
运行结果如图
运用ctrl+Z来结束文件
2.重定向和文件
- 重定向与操作系统有关,与C无关。
2.重定向输入:将words文本文件导入已经编译的一个程序中,则需要words文件与stdio流相关联。执行以下命令
./1125<words
3.重定向输出:把用./1125把键盘输入内容发送到mywords的文件中。需输入以下命令
./1125>mywords
graph TD
键盘输入字符 --> 显示器 --> mywords
简要就是以上流程
三.创建更友好的用户界面
发现一个比较有意思的代码
int main()
{
int guess=1;
printf("Pick an integer from 1to 100.I will try to guess");
printf("it.\nRespond with a y if my guess is right and with");
printf("\nan n if it is wrong .\n");
printf("Uh...is your number %d\n",guess);
while(getchar()!='y')
printf("Well,then,is it %d ?\n",++guess);
printf("I knew Icould do it!\n");
return 0;
}
运行结果如图
输入一个n,但guess递增了2次,why?这就和之前的写过的计算字符行数一样,程序读取n作为用户否定了1,还在结尾读取了换行符否定了2.