CPrimerPlus学习(七):getchar()/putchar()/ctype.h/switch/goto/编程练习

getchar()/putchar()

getchar()函数不带任何参数,它从输入队列中返回下一个字符。
例如,下面的语句读取下一个字符输入,并把该字符的值赋给变量ch:
ch = getchar();
该语句与下面的语句效果相同:
scanf("%c", &ch);

putchar()函数打印它的参数。
例如,下面的语句把之前赋给ch的值作为字符打印出来:
putchar(ch);
该语句与下面的语句效果相同:
printf("%c", ch);

由于这些函数只处理字符,所以它们比更通用的scanf()和printf()函数更 快、更简洁。而且,注意 getchar()和 putchar()不需要转换说明,因为它们只处理字符。

ctype.h

//替换输入的字母,非字母字符保持不变
#include <stdio.h>
#include <ctype.h>       // 包含isalpha()的函数原型

int main(void)
{
	char ch;
	while ((ch = getchar()) != '\n')
	{
	if (isalpha(ch))    // 如果是一个字符,
		putchar(ch + 1);  // 显示该字符的下一个字符
	else          // 否则,
		putchar(ch);    // 原样显示
	}
	putchar(ch);        // 显示换行符
	return 0;
}
/*
下面是该程序的一个输出示例,
注意大小写字母都被替换了,除了空格和标点符号:
Look! It's a programmer!
Mppl! Ju't b qsphsbnnfs!
*/

在这里插入图片描述

逻辑运算符

1、运算符
		与 &&
		或 ||
		非 !

2、假设exp1和exp2是两个简单的关系表达式:
		当且仅当exp1和exp2都为真时,exp1 && exp2才为真;
		如果exp1或exp2为真,则exp1 || exp2为真;
		如果exp1为假,则!exp1为真;如果exp1为真,则!exp1为假。

3、ios646.h头文件
		与 and
		或 or
		非 not
		
4、注意书写格式:
		//correct
		if (range >= 90 && range <= 100)
		//error
		if (90 <= range <= 100) 

举例:

// wordcnt.c -- 统计字符数、单词数、行数
#include <stdio.h>
#include <ctype.h>     // 为isspace()函数提供原型
#include <stdbool.h>    // 为bool、true、false提供定义

#define STOP '|'

int main(void)
{
	char c;        // 读入字符
	char prev;       // 读入的前一个字符
	long n_chars = 0L;    // 字符数
	int n_lines = 0;    // 行数
	int n_words = 0;    // 单词数
	int p_lines = 0;    // 不完整的行数
	bool inword = false;  // 如果c在单词中,inword 等于 true
	
	printf("Enter text to be analyzed (| to terminate):\n");
	prev = '\n';      // 用于识别完整的行
	
	while ((c = getchar()) != STOP)
	{
		n_chars++;     // 统计字符
		if (c == '\n')
			n_lines++;   // 统计行
		if (!isspace(c) && !inword)
		{
			inword = true;// 开始一个新的单词
			n_words++;   // 统计单词
		}
		if (isspace(c) && inword)
			inword = false;  // 打到单词的末尾
		prev = c;     // 保存字符的值
	}
	if (prev != '\n')
		p_lines = 1;
		
	printf("characters = %ld, words = %d, lines = %d, ",n_chars, n_words, n_lines);
	printf("partial lines = %d\n", p_lines);
	
	return 0;
}
/*
下面是运行该程序后的一个输出示例:
Enter text to be analyzed (| to terminate):
Reason is a
powerful servant but
an inadequate master .
|
characters = 55, words = 9, lines = 3, partial lines = 0
*/

条件运算符:?

x = (y < 0) ? -y : y;
在=和;之间的内容就是条件表达式,该语句的意思是:
“如果y小于0,那 么x = -y;否则,x = y”。
用if else可以这样表达:
		if (y < 0)
			x = -y;
		else
			x = y;
			
条件表达式的通用形式如下:
	expression1 ? expression2 : expression3
	//如果 expression1 为真(非 0),那么整个条件表达式的值与 expression2的值相同;
	//如果expression1为假(0),那么整个条件表达式的值与expression3的值相同。

需要把两个值中的一个赋给变量时,就可以用条件表达式。
典型的例子是,把两个值中的最大值赋给变量:
	max = (a > b) ? a : b;
	//如果a大于b,那么将max设置为a;否则,设置为b。

通常,条件运算符完成的任务用 if else 语句也可以完成。
但是,使用条件运算符的代码更简洁,而且编译器可以生成更紧凑的程序代码。

continue

3种循环都可以使用continue语句。
执行到该语句时,会跳过本次迭代的剩余部分,并开始下一轮迭代。
如果continue语句在嵌套循环内,则只会影响包含该语句的内层循环。

break

程序执行到循环中的break语句时,会终止包含它的循环,并继续执行下一阶段。
如果break语句位于嵌套循环内,它只会影响包含它的当前循环。

switch

#include <stdio.h>
#include <ctype.h>
int main(void)
{
	char ch;
	printf("Give me a letter of the alphabet, and I will give ");
	printf("an animal name\nbeginning with that letter.\n");
	printf("Please type in a letter; type # to end my act.\n");
	while ((ch = getchar()) != '#')
	{
		if ('\n' == ch)
			continue;
		if (islower(ch))
			switch (ch)
			{
			case 'a':
				printf("argali, a wild sheep of Asia\n");
				break;
			case 'b':
				printf("babirusa, a wild pig of Malay\n");
				break;
			case 'c':
				printf("coati, racoonlike mammal\n");
				break;
			case 'd':
				printf("desman, aquatic, molelike critter\n");
				break;
			case 'e':
				printf("echidna, the spiny anteater\n");
				break;
			case 'f':
				printf("fisher, brownish marten\n");
					break;
			default:
				printf("That's a stumper!\n");
			}
		else
			printf("I recognize only lowercase letters.\n");
		while (getchar() != '\n')
			continue;
		printf("Please type another letter or a #.\n");
	}
	printf("Bye!\n");

	return 0;
}

//假设用户一开始就按下Enter键,那么程序读到的首个字符就是换行 符。下面的代码处理这种情况:
if (ch == '\n')
	continue;
	

在这里插入图片描述

switch (整型表达式)
{
	case 常量1:
	语句   <--可选
	case 常量2:
	语句   <--可选
	default :   <--可选
	语句   <--可选
}
何时使用switch?何时使用if else?
	你经常会别无选择。
	如果是根据浮点类型的变量或表达式来选择,就无法使用 switch。
	如果根据变量在某范围内决定程序流的去向,使用switch就很麻烦,这种情况用if就很方便。

goto

goto语句使程序控制跳转至相应标签语句。
冒号用于分隔标签和标签语句。
标签名遵循变量命名规则。
标签语句可以出现在goto的前面或后面。

形式:
	goto label ;
	label : statement

编程练习

1
编写一个程序读取输入,读到#字符停止,
然后报告读取的空格数、换行符数和所有其他字符的数量。

#include <stdio.h>

int main(void)
{
	char ch;
	printf("Please type in a letter; type # to end.\n");

	int space_num = 0;
	int n_num = 0;
	int other = 0;

	while ((ch = getchar()) != '#')
	{
		if ('\n' == ch)
			n_num++;
		else if (' ' == ch)
			space_num++;
		else
			other++;
	}
	printf("spaces: %d, newlines: %d, others: %d \n",space_num,n_num,other);

	return 0;
}

2
编写一个程序读取输入,读到#字符停止。
程序要打印每个输入的字符以及对应的ASCII码(十进制)。
一行打印8个字符。
建议:使用字符计数和求模运算符(%)在每8个循环周期时打印一个换行符。

#include <stdio.h>

int main(void)
{
	char ch;
	printf("Please type in a letter; type # to end.\n");

	int num = 0;

	while ((ch = getchar()) != '#')
	{
		printf("%c:%d ", ch, ch);
		num++;
		if (num % 8 == 0)
			printf("\n");
	}

	return 0;
}

/*
Please type in a letter; type # to end.
abcdefghijklmnopqrstuvwxyz#
a:97 b:98 c:99 d:100 e:101 f:102 g:103 h:104
i:105 j:106 k:107 l:108 m:109 n:110 o:111 p:112
q:113 r:114 s:115 t:116 u:117 v:118 w:119 x:120
y:121 z:122
*/

3
编写一个程序,读取整数直到用户输入0。
输入结束后,程序应报告用户输入的偶数(不包括 0)个数、这些偶数的平均值、输入的奇数个数及其奇数的平均值。

//课后答案
#include <stdio.h> 

int main(void)    
{      
	int n;      
	double sumeven = 0.0;      
	int ct_even = 0;      
	double sumodd = 0.0;      
	int ct_odd = 0;             
	
	while (scanf("%d", &n) == 1 && n != 0)      
	{          
		if (n % 2 == 0)          
		{              
			sumeven += n;              
			++ct_even;          
		}          
		else  // n % 2 is either 1 or -1          
		{               
			sumodd += n;              
			++ct_odd;         
		}      
	}      
	
	printf("Number of evens: %d", ct_even);      
	if (ct_even > 0)          
		printf("  average: %g", sumeven / ct_even);      
	putchar('\n');                
	
	printf("Number of odds: %d", ct_odd);      
	if (ct_odd > 0)          
		printf("  average: %g", sumodd / ct_odd);      
	putchar('\n');      
	
	printf("\ndone\n");           
	
	return 0; 
} 

4
使用if else语句编写一个程序读取输入,读到#停止。
用感叹号替换句号,用两个感叹号替换原来的感叹号,最后报告进行了多少次替换。

#include <stdio.h>

int main(void)
{
	char ch;
	int n = 0;

	printf("please enter:");
	while ((ch = getchar()) != '#')
	{
		if (ch == '.')
		{
			putchar('!'); //注意:not printf
			n++;
		}
		else if (ch == '!')
		{
			putchar('!');
			putchar('!');
			n++;
		}
		else
		{
			putchar(ch);
		}
	}
	printf("%d times\n", n);

	return 0;
}

/*
please enter:1.2.3!!
1!2!3!!!!
*/

5
使用switch重写练习4。

#include <stdio.h>

int main(void)
{
	char ch;
	int n1 = 0;
	int n2 = 0;
	printf("please enter , enter # to quit:");
	while ((ch = getchar()) != '#')
	{
		switch (ch)      
		{
		case '.':
			putchar('!');
			n1++;
			break;
		case '!':
			putchar('!');
			putchar('!');
			n2++;
			break;
		default:
			putchar(ch);
		}
	}
	printf("\n%d times\n", n1 + n2);

	return 0;
}

/*
please enter , enter # to quit:1.2.3!!#
1!2!3!!!!
4 times
*/

6
编写程序读取输入,读到#停止,报告ei出现的次数。
注意
该程序要记录前一个字符和当前字符。
用“Receive your eieio award”这 样的输入来测试。

#include <stdio.h>

int main(void)
{
	char ch;
	int e = 0;
	int n = 0;

	printf("please enter , enter # to quit:");

	while ((ch = getchar()) != '#')
	{
		if (ch == 'e')
			e = 1;
		else if ((ch == 'i') && (e = 1))
			n++;
		e = 0;
	}

	printf("\n%d times\n", n);

	return 0;
}

/*
please enter , enter # to quit:Receive your eieio award#
3 times

please enter , enter # to quit:eieieieiei
5 times
*/

7
编写一个程序,提示用户输入一周工作的小时数,然后打印工资总额、税金和净收入。
做如下假设:
a.基本工资 = 1000美元/小时
b.加班(超过40小时) = 1.5倍的时间
c.税率: 前300美元为15%
续150美元为20%
余下的为25%
用#define定义符号常量。
不用在意是否符合当前的税法。

#include <stdio.h>

#define BT 40
#define BW 1000
#define OT 1.5
#define T1 0.15
#define T2 0.2
#define T3 0.25
#define A1 300
#define A2 150

int main(void)
{
	float t;
	float bw, tax, net;

	printf("please enter your hours:");
	scanf("%f", &t);

	if (t > 0)
	{
		if (t <= BT)
			bw = t * BW;
		else
			bw = BT * BW + (t - BT) * OT * BW;

		if (bw < A1)
			tax = bw * T1;
		else if (bw > A1  && bw <= (A1 + A2))
			tax = A1 * T1 + (bw - A1) * T2;
		else
			tax = A1 * T1 + A2 * T2 + (bw - A1 - A2) * T3;

		net = bw - tax;

		printf("Wage is %.2f Taxex is %.2f Net is %.2f\n", bw, tax, net);
	}
	else
		printf("Your hours too short\n");

	return 0;
}

/*
please enter your hours:30
Wage is 30000.00 Taxex is 7462.50 Net is 22537.50

please enter your hours:50
Wage is 55000.00 Taxex is 13712.50 Net is 41287.50
*/

8
修改练习7的假设a,让程序可以给出一个供选择的工资等级菜单。
使用switch完成工资等级选择。
运行程序后,显示的菜单应该类似这样:


Enter the number corresponding to the desired pay rate or action:

  1. $8.75/hr              2) $9.33/hr
  2. $10.00/hr             4) $11.20/hr
  3. quit

如果选择 1~4 其中的一个数字,程序应该询问用户工作的小时数。
程序要通过循环运行,除非用户输入5。
如果输入 1~5 以外的数字,程序应提醒用户输入正确的选项,然后再重复显示菜单提示用户输入。
使用#define创建符号常量表示各工资等级和税率。

#include <stdio.h>

#define BT 40
#define OT 1.5
#define T1 0.15
#define T2 0.2
#define T3 0.25
#define A1 300
#define A2 150
#define BW1 8.75
#define BW2 9.33
#define BW3 10.00
#define BW4 11.20

void menu();

int main(void)
{
	int n;
	float t;
	float BW;
	float bw, tax, net;

	menu();

	printf("Your choice:");

	while (scanf("%d", &n) != 0)
	{
		if (n > 0 && n < 5)
		{
			switch (n)
			{
			case 1:
				BW = BW1;
				break;
			case 2:
				BW = BW2;
				break;
			case 3:
				BW = BW3;
				break;
			case 4:
				BW = BW4;
				break;
			}

			printf("please enter your hours:");
			scanf("%f", &t);

			if (t > 0)
			{
				if (t <= BT)
					bw = t * BW;
				else
					bw = BT * BW + (t - BT) * OT * BW;

				if (bw < A1)
					tax = bw * T1;
				else if (bw > A1  && bw <= (A1 + A2))
					tax = A1 * T1 + (bw - A1) * T2;
				else
					tax = A1 * T1 + A2 * T2 + (bw - A1 - A2) * T3;

				net = bw - tax;

				printf("Wage is %.2f Taxex is %.2f Net is %.2f\n", bw, tax, net);
			}
			else
				printf("Your hours too short\n");
			menu();
		}
		else if (n == 5)
			break;
		else
		{
			printf("Please re-enter!\n");
			menu();
		}
	}

	return 0;
}

void menu()
{
	printf("Enter the number corresponding to the desired pay rate or action:\n");
	printf("1) $8.75  / hr\n");
	printf("2) $9.33  / hr\n");
	printf("3) $10.00 / hr\n");
	printf("4) $11.20 / hr\n");
	printf("5) quit\n");
}
/*
Enter the number corresponding to the desired pay rate or action:
1) $8.75  / hr
2) $9.33  / hr
3) $10.00 / hr
4) $11.20 / hr
5) quit
Your choice:0
Please re-enter!

Enter the number corresponding to the desired pay rate or action:
1) $8.75  / hr
2) $9.33  / hr
3) $10.00 / hr
4) $11.20 / hr
5) quit
2
please enter your hours:50
Wage is 513.15 Taxex is 90.79 Net is 422.36

Enter the number corresponding to the desired pay rate or action:
1) $8.75  / hr
2) $9.33  / hr
3) $10.00 / hr
4) $11.20 / hr
5) quit
5
*/

9
编写一个程序,只接受正整数输入,然后显示所有小于或等于该数的素数。

习题答案:
链接:https://pan.baidu.com/s/1BoOvG7lHztEFGm3ypjgU7A 提取码:t6k0

#include <stdio.h>
#include <stdbool.h> 

int main(void) 
{ 
	int limit;    
	int num;  
	int div;  
	bool numIsPrime;  // use int if stdbool.h not available     

	printf("Enter a positive integer: "); 

	while (scanf("%d", &limit) == 1 && limit > 0)   
	{       
		if (limit > 1)       
			printf("Here are the prime numbers up through %d\n", limit);     
		else       
			printf("No primes.\n");   

		for (num = 2; num <= limit; num++)         
		{            
			for (div = 2, numIsPrime = true; (div * div) <= num; div++)    
				if (num % div == 0)        
					numIsPrime = false;       

			if (numIsPrime)            
				printf("%d is prime.\n", num);      
		}        
		printf("Enter a positive integer (q to quit): ");    
	}    
	printf("Done!\n");  

	return 0; 
} 

10
1988年的美国联邦税收计划是近代最简单的税收方案。
它分为4个类别,每个类别有两个等级。
下面是该税收计划的摘要(美元数为应征税的收入):
在这里插入图片描述
例如,一位工资为20000美元的单身纳税人,应缴纳税费0.15×17850+0.28×(20000−17850)美元。
编写一个程序,让用户指定缴纳税金的种类和应纳税收入,然后计算税金。
程序应通过循环让用户可以多次输入。

#include <stdio.h>

int menu()
{
	int type;

	printf("Types and Taxes:\n");
	printf("		1.single     17850.00\n");
	printf("		2.head       23900.00\n");
	printf("		3.married    29750.00\n");
	printf("		4.divorced   14875.00\n");
	printf("		5.exit\n");

	printf("Please enter your type:\n");
	scanf("%d", &type);

	return type;
}

int main(void) 
{ 
	int type;
	double B;
	double wage;
	double tax;

	do
	{
		type = menu();

		if (type == 5)
			break;

		switch (type)
		{
		case 1:
			B = 17850.00;
			break;
		case 2:
			B = 23900.00;
			break;
		case 3:
			B = 29750.00;
			break;
		case 4:
			B = 14875.00;
			break;
		}

		printf("Please enter your wages:\n");
		scanf("%lf", &wage);

		if (wage > 0)
		{
			if (wage < B)
			{
				tax = wage * 0.15;
			}
			else
			{
				tax = B * 0.15 + (wage - B) * 0.28;
			}
			printf("Your taxes is %.2f\n", tax);
		}
		else
			printf("error");

	} while (1);

	return 0; 
} 

/*
Types and Taxes:
				1.single     17850.00
				2.head       23900.00
				3.married    29750.00
				4.divorced   14875.00
				5.exit
Please enter your type:
1
Please enter your wages:
50000
Your taxes is 11679.50

Types and Taxes:
				1.single     17850.00
				2.head       23900.00
				3.married    29750.00
				4.divorced   14875.00
				5.exit
Please enter your type:
5

若要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口...
*/

11
ABC邮购杂货店出售的洋蓟售价为 2.05 美元/磅,甜菜售价为 1.15 美元/磅,胡萝卜售价为 1.09美元/磅。
在添加运费之前,100美元的订单有 5%的打折优惠。
少于或等于5磅的订单收取6.5美元的运费和包装费,5磅~20磅的订单收取14美元的运费和包装费,超过20磅的订单在14美元的基础上每续重1磅增加0.5美元。
编写一个程序,在循环中用switch语句实现用户输入不同的字母时有不同的响应,即输入a的响应是让用户输入洋蓟的磅数,b 是甜菜的磅数,c是胡萝卜的磅数,q 是退出订购。
程序要记录累计的重量。
即,如果用户输入4 磅的甜菜,然后输入5磅的甜菜,程序应报告9磅的甜菜。
然后,该程序要计算货物总价、折扣(如果有的话)、运费和包装费。
随后,程序应显示所有的购买信息:物品售价、订购的重量(单位:磅)、订购的蔬菜费用、订单的总费用、折扣(如果有的话)、运费和包装费,以及所有的费用总额。

#include <stdio.h>
#include <string.h>

//洋蓟   artichokes
//甜菜   sugar beet
//胡萝卜 carrot

#define AP 2.05
#define SP 1.15
#define CP 1.09

void menu()
{
	printf("What do you want:\n");
	printf("a. artichokes\n");
	printf("b. sugar beet\n");
	printf("c. carrot\n");
	printf("q. exit\n");
}

int main(void) 
{ 
	char ch;
	float n;
	float sum = 0;
	float P;
	float price;
	float sum_price = 0;
	float end_price;
	float count = 0;
	float fp; //运费包装费 freight and packing
	float num[32];
	float unit[32];
	char type[32];
	int i = 1;

	menu();
	printf("Please enter:");
	scanf("%s", &ch);

	if (ch != 'q' && ch != 'a' && ch != 'b' && ch != 'c')
	{
		printf("error\n\n");
		menu();
		printf("Please enter:");
		scanf("%s", &ch);
	}

	while (ch != 'q')
	{
		switch (ch)
		{
		case 'a':
			printf("How many pounds of artichokes do you need? ");
			P = AP;
			break;
		case 'b':
			printf("How many pounds of sugar beets do you need? ");
			P = SP;
			break;
		case 'c':
			printf("How many pounds of carrots do you need? ");
			P = CP;
			break;
		}

		scanf("%f", &n);
		num[i] = n;
		sum = sum + n;
		price = n * P;
		unit[i] = P;
		type[i] = ch;
		sum_price = sum_price + price;
		i++;

		menu();
		printf("Please enter:");
		scanf("%s", &ch);
	}

	if (ch == 'q')
	{
		if (sum_price >= 100)
		{
			count = 0.05;
		}

		if (sum <= 5)
		{
			fp = 6.5;
		}
		else if (sum > 5 && sum <= 20)
		{
			fp = 14;
		}
		else
		{
			fp = 14 + (sum - 20) * 0.5;
		}

		end_price = sum_price - sum_price * count + fp;

		char ty[32] = "";
		for (int k = 1; k <= i - 1; k++)
		{
			switch (type[k])
			{
			case 'a':
				strcat(ty, "artichokes");
				break;
			case 'b':
				strcat(ty, "sugar beet");
				break;
			case 'c':
				strcat(ty, "carrot    ");
				break;
			}

			printf("类别            单价            重量            总计\n");
			printf("%s %9.2f %15.2f %16.2f\n\n", ty,unit[k], num[k], unit[k] * num[k]);
			memset(ty, 0, sizeof(ty)); //清空字符串
		}

		printf("总价             %.f\n\n", sum_price);
		printf("折扣      运包费    总费用\n");
		printf("%.2f %10.2f %10.2f\n", count, fp, end_price);
	}

	return 0; 
} 

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值