第八章 字符输入/输出和输入确认


编程练习:

下面的一些程序要求输入以EOF终止。如果您的操作系统难以使用或不能使用重定向,则使用一些其他的判断来终止输入,例如读取&字符。

  1. 设计一个程序,统计输入到文件结尾的字符数。

#include <stdio.h>

int main(void)
{
	int count = 0;

	while (getchar() != EOF)
		count++;
	printf("输入的字符总数:%d\n", count);

	return 0;
}


2.编写一个程序,把输入作为字符流读取,直到遇到EOF。令该程序打印每个输入字符及其ASCII编码的十进制值。注意在ASCII序列中空格字符前面的字符是非打印字符,要特殊处理这些字符。如果非打印字符是换行符或制表符,则分期打印\n或\t。否则,使用控制字符符号。例如,ASCII的1是Ctrl+A,可以显示为^A。注意A的ASCⅡ值是Ctrl+A的值加64。对其他非打印字符也保持相似的关系。除去每次遇到一个换行符时就开始一个新行之外,每行打印10对值。

# include <stdio.h>
# define ENTER '\n'
# define TAB '\t'
# define BLANK ' '

int main(void)
{
	int input[100];
	int conut = 1;
	int i = 0;

	while ((input[i++] = getchar()) != EOF)
		;
	for (i = 0; input[i] != EOF; i++)
	{
		if (input[i] == ENTER)
			printf("\\n|%-4d", input[i]);
		else if (input[i] == TAB)
			printf("\\t|%-4d", input[i]);
		else if (input >= 0 && input < BLANK)
			printf("%c|%-4d", input[i] + 64, input[i]);
		else
			printf("%c|%-4d", input[i], input[i]);
		if (conut++ % 10 == 0)
			putchar(ENTER);
	}
	putchar(ENTER);

	return 0;
}



3.编写一个程序,把输入作为字符流读取,直至遇到EOF。令其报告输入中的大写字母个数和小写字母个数。假设小写字母的数值是连续的,大写字母也是如此。或者你可以使用ctypc.h库中的合适的函数来区分大小写。

#include <stdio.h>
#include <ctype.h>

int main(void)
{
	char ch;
	int count_x = 0;
	int count_d = 0;

	while ((ch = getchar(0)) != EOF)
	{
		if (islower(ch))
			count_x++;
		else if (isupper(ch))
			count_d++;
	}
	printf("大写字母个数:%d\n小写字母个数:%d\n", count_d, count_x);

	return 0;
}


4.编写一个程序,把输入作为字符流读取,直至遇到EOF。令其报告每个单词的平均字母数。不要将空白字符记为单词中的字母。实际上,标点符号也不应该计算,但现在不必考虑这一点

(如果您想做得好一些,可以考虑使用ctype.h系列中的ispunct()函数)。

#include <stdio.h>
#include <ctype.h>

int main(void)
{
	char ch;
	int count_word = 0;
	int count_letter = 0;
	int i = 0;

	while ((ch = getchar()) != EOF)
	{
		if (isalpha(ch))
		{
			i = 1;
			count_letter++;
		}

		else if (1 == i)
		{
			count_word++;
			i = 0;
		}
	}
	printf("单词个数:%d\n", count_word);
	printf("字母个数:%d\n", count_letter);
	printf("每个单词的平均字母数:%.2f\n", 
		(float)count_letter/(float)count_word);

	return 0;
}


5,修改程序清单8,4中的猜测程序,使其使用更智能的猜测策略。例如,程序最初猜50,让其询问用户该猜测值是大、小还是正确。如果该猜测值小,则令下一次猜测值为50和100的中值,也就是75。如果75大,则下一次猜测值为75和50的中值,等等。使用这种二分搜索(binary search)策略,起码如果用户没有欺骗,该程序很快会获得正确答案。

#include <stdio.h>
#include <ctype.h>

int main(void)
{
	int big = 100;
	int small = 1;
	int guess = 50;
	char ch;

	printf("猜数程序(1-100),计算机将给出一数字,请做出相应的提示。\n");
	printf("例如:数字太大请输入b、数字太小请输入s、猜对了请输入y。\n");

	printf("电脑:%d\n", guess);
	while ((ch = getchar()) != 'y')
	{
		while (getchar() != '\n')
			;
		switch (ch)
		{
		case 'b': 
			printf("人:数字太大了\n");
			big = guess;
			guess = (small + guess)  / 2;
			break;
		case 's': 
			printf("人:数字太小了\n");
			small = guess;
			guess = (big + guess) / 2;
			break;
		default:
			printf("电脑:我只是个计算机啊,说好的提示呢?\n");
			continue;
		}
		printf("电脑:%d\n", guess);
	}
	if ('y' == ch)
		printf("人:你竟然猜对了!!\n");
		printf("电脑:哈哈哈……我可是无所不知的计算机啊。\n");


	return 0;
}



6.修改程序清单8.8中的get_first()函数,使其返回所遇到的第一个非空白字符。在一个简单的程序中测试该函数。

#include <stdio.h>
#include <ctype.h>
char get_first(void);

int main(void)
{
	char ch;
	while ((ch = get_first()) != EOF)
	{
		putchar(ch);
	}
	return 0;
}

char get_first(void)
{
	int ch;
	while (isspace(ch = getchar()));
	while (getchar() != '\n');
	return ch;
}



7.修改第7章的练习8,使菜单选项由字符代替数字进行标记。

#include <stdio.h>

#define LIMIT1 300
#define TAX1 0.15
#define LIMIT2 150
#define TAX2 0.2
#define LIMIT3 450
#define TAX3 0.25
#define TIME 40
#define ADD 1.5
#define BASE1 8.75
#define BASE2 9.33
#define BASE3 10.00
#define BASE4 11.20

void menu(void);
void fun(float base);
char getfirst(void);

int main(void)
{

	char ch;

	menu();

	while ((ch = getfirst()) != 'q')
	{
		switch (ch)
		{
		case 'a': fun(BASE1);
			break;
		case 'b': fun(BASE2);
			break;
		case 'c': fun(BASE3);
			break;
		case 'd': fun(BASE4);
			break;
		default: printf("请输入正确的选项同(a b c d or q):");
		}
		putchar('\n');
		menu();
	}

	return 0;
}

void menu(void)
{
	printf("Enter the number corresponding to");
	printf(" the desired pay rate or action :\n");
	printf("a) $8.75 / hr         b) $9.33 / hr \n");
	printf("c) $lO.OO / hr        d) $11.20 / hr\n");
	printf("q) quit\n");
}

void fun(float base)
{
	float time;
	float total, tax, salary;

	printf("请输入一周工作的时间(小时):");
	scanf("%f", &time);
	if (time > TIME)
		time = (time - TIME) * ADD + TIME;

	total = time * base;

	if (total <= LIMIT1)
		tax = total * TAX1;
	else if (total <= LIMIT3)
		tax = LIMIT1 * TAX1 + (total - LIMIT1) * TAX2;
	else
		tax = LIMIT1 * TAX1 + LIMIT2 * TAX2 + (total - LIMIT3) * TAX3;

	salary = total - tax;


	printf("本周总工资:%.2f;税金:%.2f;实际工资:%.2f\n",
		total, tax, salary);
}

char getfirst(void)
{
	char ch;
	ch = getchar();
	while (isspace(ch))
		ch = getchar();
	while (getchar() != '\n')
		;

	return ch;

}


8.编写一个程序,显示一个菜单,为您提供加法、减法、乘法或除法的选项。获得您的选择后,该程序请求两个数,然后执行您选择的操作。该程序应该只接受它所提供的菜单选项。它应该使用float类型的数,并且如果用户未能输入数字应允许其重新输入。在除法的情况中,如果用户输入O作为第二个数,该程序应该提示用户输入一个新的值。一个典型的程序运行应该如下所示:

Enter the operation of your choice:

a. add       s. subtract

m. multiply   d. divide

q. quit

a

Enter first number: 22.4

Enter second number: one

one is not an number.

Please enter a number, such as 2.5. -1.78E8, or 3. 1

22.4 + 1 = 23.4

Enter the operation of your choice:

a. add        s. subtract

m. multiply   d. divide

q. quit

d

Enter first number: 18.4

Enter second number: O

Enter a number other than 0: 0.2

18.4 / 0.2 = 92

Enter the operation of your choice:

a. add        s. subtract

m. multiply   d. divide

q. quit

q

Bye.

#include <stdio.h>
#include <ctype.h>
void menu(void);
char input_ch(void);
float input_num(void);

int main(void)
{
	char ch;
	float sum1, sum2;

	menu();
	while ((ch = input_ch()) != 'q')
	{
		printf("Enter first number:");
		sum1 = input_num();
		printf("Enter second number:");
		sum2 = input_num();
		switch (ch)
		{
		case 'a': printf("%.1f + %.1f = %.1f\n", sum1, sum2, sum1 + sum2);
			break;
		case 's': printf("%.1f - %.1f = %.1f\n", sum1, sum2, sum1 - sum2);
			break;
		case 'm': printf("%.1f * %.1f = %.1f\n", sum1, sum2, sum1 * sum2);
			break;
		case 'd':;
			while (sum2 == 0.00)
			{
				printf("Enter a number other than 0:");
				sum2 = input_num();
			}
			printf("%.1f / %.1f = %.1f\n", sum1, sum2, sum1 / sum2);
			break;
		default: printf("Error! please response with a,s,m,d or q: ");
			;

		}
		menu();
	}
	printf("Bye.\n");

	return 0;
}

void menu(void)
{
	printf("Enter the operation of your choice:\n");
	printf("a.add		s.subtract\n");
	printf("m.multiply	d.divide\n");
	printf("q.quit\n");
}

char input_ch(void)
{
	char ch;
	while (ch = getchar())
	{
		while (isspace(ch))
			ch = getchar();
		while (getchar() != '\n')
			;
		if (ch != 'a' && ch != 's' && ch != 'm' && ch != 'd' && ch != 'q')
			printf("Error! please response with a,s,m,d or q: ");
		else
			return ch;
	}
}

float input_num(void)
{
	float number;
	char ch;
	while (scanf("%f", &number) != 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.:");
	}

	return number;
}