tips: EOF需要先回车再ctrl+D,我的环境是windows+clion
1.设计一个程序,统计在读到文件结尾之前读取的字符数。
#include <stdio.h>
int main(void ){
int count = 0;
while ((getchar())!= EOF){
count++;
}
printf("The number of charactors is %d", count);
return 0;
}
2.编写一个程序,在遇到 EOF 之前,把输入作为字符流读取。程序要打印每个输入的字符及其相应的ASCII十进制值。注意,在ASCII序列中,空格字符前面的字符都是非打印字符,要特殊处理这些字符。如果非打印字符是换行符或制表符,则分别打印\n或\t。否则,使用控制字符表示法。例如,ASCII的1是Ctrl+A,可显示为^A。注意,A的ASCII值是Ctrl+A的值加上64。其他非打印字符也有类似的关系。除每次遇到换行符打印新的一行之外,每行打印10对值。(注意:不同的操作系统其控制字符可能不同。)
#include <stdio.h>
int main(void ){
char ch;
int num;
while ((ch = getchar())!=EOF){
switch (ch) {
case '\n':
printf("\\n");
break;
case '\t':
printf("\\t");
break;
default:
if(ch<' '){
putchar('^');
putchar(ch+64);
printf(":%d ",ch);
}
else{
putchar(ch);
printf(":%d ",ch);
break;
}
}
num++;
if(num%10 == 0){
putchar('\n');
}
}
return 0;
}
3.编写一个程序,在遇到 EOF 之前,把输入作为字符流读取。该程序要报告输入中的大写字母和小写字母的个数。假设大小写字母数值是连续的。或者使用ctype.h库中合适的分类函数更方便。
#include <stdio.h>
#include <ctype.h>
int main(void ){
int ch;
int lownum=0;
int upnum=0;
int otrnum=0;
while ((ch = getchar())!=EOF){
if(isupper(ch)){
upnum++;
} else if(islower(ch)){
lownum++;
} else{
otrnum++;
}
}
printf("upper charactors: %d\n",upnum);
printf("lower charactors: %d\n",lownum);
printf("other charactors: %d\n",otrnum);
return 0;
}
4.编写一个程序,在遇到EOF之前,把输入作为字符流读取。该程序要报告平均每个单词的字母数。不要把空白统计为单词的字母。实际上,标点符号也不应该统计,但是现在暂时不同考虑这么多(如果你比较在意这点,考虑使用ctype.h系列中的ispunct()函数)。
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
int main(void ){
char ch;
int num;
int wnum=1;
float svgnum;
while ((ch = getchar())!=EOF){
switch (ch) {
case ' ':
wnum++;
break;
default:
num++;
break;
}
}
svgnum = num/wnum;
printf("%d\n",wnum);
printf("%.2f",svgnum);
}
5.修改程序清单8.4的猜数字程序,使用更智能的猜测策略。例如,程序最初猜50,询问用户是猜大了、猜小了还是猜对了。如果猜小了,那么下一次猜测的值应是50和100中值,也就是75。如果这次猜大了,那么下一次猜测的值应是50和75的中值,等等。使用二分查找(binary search)策略,如果用户没有欺骗程序,那么程序很快就会猜到正确的答案。
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
int main(void ){
int num=50;
char guess[2]; // 这里涉及到C的一个特性,如果不是数组的话,无法正常获取字符。
int max=100,min=1;
printf("you num is 1-100\n");
printf("yout num is %d ?\n",num);
printf("if I guess bigger,Enter \"b\" \n");
printf("if I guess smaller,Enter \"s\" \n");
printf("if I guess right,Enter \"y\" \n");
while ((scanf("%s",guess))==1){
if(guess[0] == 'b'){
max = num;
num = (max+min)/2;
printf("yout num is %d ?",num);
}
else if(guess[0] == 's'){
min = num;
num = (max+min)/2;
printf("yout num is %d ?",num);
}
else if(guess[0] == 'y'){
printf("I knew it!,the num is %d",num);
break;
}
else{
printf("your must enter \"b\" or \"s\".");
}
}
return 0;
}
6.修改程序清单8.8中的get_first()函数,让该函数返回读取的第1个非空白字符,并在一个简单的程序中测试。
/*
char get_first(void)
{
int ch;
ch = getchar();
while(getchar() != '\n')
continue;
return ch;
}
*/
#include<stdio.h>
char get_first(void);
int main(void)
{
printf("%c", get_first());
}
char get_first(void)
{
int ch;
ch = getchar();
while (ch == ' ') {
ch = getchar();
}
return ch;
}
7.修改第7章的编程练习8,用字符代替数字标记菜单的选项。用q代替5作为结束输入的标记。
#include <stdio.h>
#include <stdlib.h>
#define salary1 8.75
#define salary2 9.33
#define salary3 10.00
#define salary4 11.20
#define OVER 1.5
#define rate1 0.15
#define rate2 0.2
#define rate3 0.25
int main(void)
{
int hour,allmoney;
char num;
float ratemoney,realmoney;
printf("Enter the number corresponding to the desired pay rate or action::\n");
printf("===================================\n");
printf("a) $8.75/hr\t");
printf("b) $9.33/hr\n");
printf("c) $10.00/hr\t");
printf("d) $11.20/hr\n");
printf("q) quit\n");
printf("===================================\n");
while(scanf("%c",&num)&& num!='q'){
if((num!='a')&&(num!='b')&&(num!='c')&&(num!='d')&&(num!='q')){
printf("your input is not valid!");
}
printf("Enter your work hour:");
scanf("%d",&hour);
if(hour>40){
hour = hour + (hour-40)*OVER;
}
switch (num) {
case 'a':
allmoney = hour*salary1;
break;
case 'b':
allmoney = hour*salary2;
break;
case 'c':
allmoney = hour*salary3;
break;
case 'd':
allmoney = hour*salary4;
break;
}
if (allmoney <= 300) {
ratemoney = allmoney * rate1;
}
else if (300 < allmoney && allmoney < 450) {
ratemoney = 300 * rate1 + (allmoney - 300) * rate2;
}
else {
ratemoney = 300 * rate1 + 150 * rate2 + (allmoney - 300 - 15) * rate3;
}
realmoney = allmoney - ratemoney;
printf("%d %.2f %.2f\n",allmoney,ratemoney,realmoney);
printf(" \n");
printf("Enter the number corresponding to the desired pay rate or action::\n");
printf("===================================\n");
printf("a) $8.75/hr\t");
printf("b) $9.33/hr\n");
printf("c) $10.00/hr\t");
printf("d) $11.20/hr\n");
printf("q) quit\n");
printf("===================================\n");
}
return 0;
}
8.编写一个程序,显示一个提供加法、减法、乘法、除法的菜单。获得用户选择的选项后,程序提示用户输入两个数字,然后执行用户刚才选择的操作。该程序只接受菜单提供的选项。程序使用float类型的变量储存用户输入的数字,如果用户输入失败,则允许再次输入。进行除法运算时,如果用户输入0作为第2个数(除数),程序应提示用户重新输入一个新值。
#include <stdio.h>
#include <ctype.h>
char get_choice(void); // (返回标签选项a\s\m\d\q)并且打印图形交互界面
char get_first(void); // (返回第一个非空白字符)读取字符,并丢弃剩余的字符
float get_float(void); // (返回读入一个float类型)读入一个float类型并判断排除非数字类型
void add(void); // 加法
void subtract(void); // 减法
void multiply(void); // 乘法
void divide(void); // 除法
int main(int argc, char const *argv[])
{
char ch;
while ( (ch = get_choice()) != 'q' )
{
switch ( ch )
{
case 'a': add();
break;
case 's': subtract();
break;
case 'm': multiply();
break;
case 'd': divide();
break;
default: printf("对不起,程序出现故障!");
break;
}
}
printf("Bye.\n");
return 0;
}
char get_choice(void)
{
char ch;
printf("Enter the operation of your choice:\n");
printf("a. add s. subtract\n");
printf("m. multiply d. divide\n");
printf("q. quit\n");
ch = get_first();
while ( (ch != 'a' && ch != 's' && ch != 'm' && ch != 'd') && ch != 'q' )
{
printf("Please respond with a, s, m, d, or q.\n");
ch = get_first();
}
return ch;
}
char get_first(void)
{
int ch;
while ( (ch = getchar()) != EOF ) //不断循环直到判断出非空白字符
{
if ( !isspace(ch) ) // 判断非空白字符
{
while ( getchar() != '\n' ) //将非空白字符后的所有字符跳过
{
continue;
}
break;
}
}
return ch;
}
void add(void)
{
float n1, n2;
printf("Enter first number:");
n1 = get_float();
printf("Enter second number:");
n2 = get_float();
printf("%.1f + %.1f = %.1f\n", n1, n2, n1 + n2);
}
void subtract(void)
{
float n1, n2;
printf("Enter first number:");
n1 = get_float();
printf("Enter second number:");
n2 = get_float();
printf("%.1f - %.1f = %.1f\n", n1, n2, n1 - n2);
}
void divide(void)
{
float n1, n2;
printf("Enter first number:");
n1 = get_float();
printf("Enter second number:");
n2 = get_float();
while ( n2 == 0 )
{
printf("Enter a number otuer than 0: ");
n2 = get_float();
}
printf("%.1f / %.1f = %.1f\n", n1, n2, n1 / n2);
}
void multiply(void)
{
float n1, n2;
printf("Enter first number:");
n1 = get_float();
printf("Enter second number:");
n2 = get_float();
printf("%.1f * %.1f = %.1f\n", n1, n2, n1 * n2);
}
float get_float(void)
{
float f;
char ch;
while ( scanf("%f", &f) != 1 ) //这里还剩下一个换行符;【如果读取的是一个非数字,则进入循环】
{
while ( (ch = getchar()) != '\n') // 打印读入错误的字符,并跳过
{
putchar(ch);
}
printf(" is not an number.\n");
printf("Please enter a number , such as 2.5, -1.78E8, or 3:" );
}
while ( getchar() != '\n') // 跳过第一个外层while的一个换行符。
{
continue;
}
return f;
}