程序清单8.1,echo.c:
/* echo.c -- 重复输入 */
#include <stdio.h>
int main(void)
{
char ch;
while ((ch = getchar()) != '#')
putchar(ch);
return 0;
}
输出结果:
程序清单8.2,echo_eof.c:
/* echo_eof.c -- 重复输入,直到文件结束 */
#include <stdio.h>
int main(void)
{
int ch;
while ((ch = getchar()) != EOF)
putchar(ch);
return 0;
}
输出结果:
程序清单8.3,file_eof.c:
// file_eof.c -- 打开一个文件并显示该文件
#include <stdio.h>
#include <stdlib.h> // 提供 exit() 函数原型
int main(void)
{
int ch;
FILE * fp;
char fname[50]; // 存储文件名
printf("Enter the name file: ");
scanf("%s", fname);
fp = fopen(fname, "r"); // 打开待读取文件(只读)
if (fp == NULL) // 如果打开失败
{
printf("Failed to open file. Bye\n");
exit(1); // 退出程序
}
while ((ch = getc(fp)) != EOF)
putchar(ch);
fclose(fp); // 关闭文件
return 0;
}
打开的文件,a.txt:
adasf
输出结果:
程序清单8.4,guess.c:
/* guess.c -- 一个拖沓且错误的猜数字程序 */
#include <stdio.h>
int main(void)
{
int guess = 1;
char response;
printf("Pick an integer from 1 to 100. I will try to guess ");
printf("it.\n Responde 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 ((response = getchar()) != 'y')
{
if (response == 'n')
printf("Well, then, is it %d?\n", ++guess);
else
printf("Sorry, I understand only y or n.\n");
while (getchar() != '\n')
continue;
}
printf("I know I could do it!\n");
return 0;
}
输出结果:
程序清单8.6(更正版本的8.5),showchar1.c:
/* showchar1.c -- 有较大I/O 问题的程序 */
#include <stdio.h>
void display(char cr, int lines, int width);
int main(void)
{
int ch; // 待打印字符
int rows, cols; // 行数和列数
printf("Enter a character and two integers:\n");
while ((ch = getchar()) != '\n')
{
if (scanf("%d %d", &rows, &cols) != 2)
break;
display(ch, rows, cols);
while (getchar() != '\n')
continue;
printf("Enter another character and two integers: \n");
printf("Enter a newline to quit.\n");
}
printf("Bye.\n");
return 0;
}
void display(char cr, int lines, int width)
{
int row, col;
for (row = 1; row <= lines; row++)
{
for (col = 1; col <= width; col++)
putchar(cr);
putchar('\n'); // 结束一行并开始新的一行
}
}
输出结果:
程序清单8.7,checking.c:
//checking.c -- 输入验证
#include <stdio.h>
#include <stdbool.h>
//验证输入是一个整数
long get_long(void);
//验证范围的上下限是否有效
bool bad_limits(long begin, long end,
long low, long high);
//计算a~b之间的整数平方和
double sum_squares(long a, long b);
int main(void)
{
const long MIN = -10000000L; //范围的下限
const long MAX = +10000000L; //范围的上限
long start; //用户指定的范围最小值
long stop; //用户指定的范围最大值
double answer;
printf("This program computes the sum of the squares of "
"integers in a range.\nThe lower bound should not "
"be less than -10000000 and\n the npper bound "
"should not be more than +10000000.\nEnter the "
"limits (enter 0 for both limits to quit):\n"
"lower limit: ");
start = get_long();
printf("upper limit: ");
stop = get_long();
while (start != 0 || stop != 0)
{
if (bad_limits(start, stop, MIN, MAX))
printf("Please try again.\n");
else
{
answer = sum_squares(start, stop);
printf("The sum of the squares of the integers ");
printf("from %ld to %ld id %g\n",
start, stop, answer);
}
printf("Enter the limits (enter 0 for both "
"limits to quit):\n");
printf("lower limit: ");
start = get_long();
printf("upper limit: ");
stop = get_long();
}
printf("Done.\n");
return 0;
}
long get_long(void)
{
long input;
char ch;
while (scanf("%ld", &input) != 1)
{
while ((ch = getchar()) != '\n')
putchar(ch);
printf(" is not an integer.\nPlease enter an ");
printf("integer value, such as 25, -178, or 3: ");
}
return input;
}
double sum_squares(long a, long b)
{
double total = 0;
long i;
for (i = a; i <= b; i++)
total += (double) i * (double) i;
return total;
}
bool bad_limits(long begin, long end,
long low, long high)
{
bool not_good = false;
if (begin > end)
{
printf("%ld isn't smaller than %ld.\n", begin, end);
not_good = true;
}
if (begin < low || end <low)
{
printf("Values must be %ld or greater.\n", low);
not_good = true;
}
if (begin > high || end > high)
{
printf("Values must be %ld or less.\n", high);
not_good = true;
}
return not_good;
}
输出结果:
程序清单8.8,menuette.c:
/*menuette.c -- 菜单程序 */
#include <stdio.h>
char get_choice(void);
char get_first(void);
int get_int(void);
void count(void);
int main(void)
{
int choice;
while ((choice = get_choice()) != 'q')
{
switch (choice)
{
case 'a': printf("Buy low, sell high.\n");
break;
case 'b': putchar('\a');
break;
case 'c': count();
break;
default: printf("Program error!\n");
break;
}
}
printf("Bye.\n");
}
void count(void)
{
int n, i;
printf("Count how far? Enter an integer: \n");
n = get_int();
for (i = 1; i <= n; i++)
printf("%d\n", i);
while (getchar() != '\n')
continue;
}
char get_choice(void)
{
int ch;
printf("Enter the letter of your choice: \n");
printf("a. advice b. bell\n");
printf("c. count q. quit.\n");
ch = get_first();
while ((ch < 'a' || ch > 'c') && ch != 'q')
{
printf("Please respond with a, b, c, or q.\n") ;
ch = get_first();
}
return ch;
}
char get_first(void)
{
int ch;
ch = getchar();
while (getchar() != '\n')
continue;
return ch;
}
int get_int(void)
{
int input;
char ch;
while (scanf("%d", &input) != 1)
{
while ((ch = getchar()) != '\n')
putchar(ch); //发现错误读空缓冲区并输出
printf(" is not an integer.\nPlease enter an ") ;
printf("integer value, such as 25, -178, or 3: ");
}
return input;
}
输出结果:
编程练习
题目1,方法:统计字符数量。示例代码8_1.c:
#include <stdio.h>
int main(void)
{
int ch, n;
n = 0;
printf("Please input some characters: ");
while ((ch = getchar()) != '&')
n++;
printf("You have input %d of characters.\n", n);
return 0;
}
输出结果:
题目2,方法:打印字符及其ASCII码。示例代码8_2.c:
#include <stdio.h>
int main(void)
{
int ch;
int n = 0;
printf("Please input some characters: ");
while ((ch = getchar()) != '&')
{
if (ch >= 32)
printf("Ch:%c ASCII:%d ", ch, ch);
else if (ch == '\n')
printf("Ch:\\n ASCII:%d ", ch);
else if (ch == '\t')
printf("Ch:\\t ASCII:%d ", ch);
else
printf("Ch:^%c ASCII:%d ", ch + 64, ch);
puts("\nYou can input again: ");
if (++n == 10)
{
n = 0;
putchar('\n');
}
}
puts("\nDone.");
return 0;
}
输出结果:
题目3,方法:统计不同类型字符数量。示例代码8_3.c:
#include <stdio.h>
#include <ctype.h>
int main(void)
{
int ch;
int upper = 0, lower = 0, other = 0;
printf("Please inpute some characters: ");
while ((ch = getchar()) != '&')
{
if (isupper(ch))
upper++;
else if (islower(ch))
lower++;
else
other++;
}
printf("Upper:%3d\n", upper);
printf("Lower:%3d\n", lower);
printf("Other:%3d\n", other);
return 0;
}
输出结果:
题目4,方法:统计字符串中单词数量。示例代码8_4.c:
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
int main(void)
{
char ch; // 输入字符
int l_num, w_num; // 字母、单词数量
float average; // 平均每个单词字母数
bool inword; // 判断是否仍在单词内部
l_num = w_num = 0;
average = 0.0;
inword = false;
printf("Please input some characters(& to quit): ");
while ((ch = getchar()) != '&')
{
if (isalpha(ch) )
{
l_num++;
if (inword == false)
{
inword = true;
w_num++;
}
}
if (isspace(ch) || ispunct(ch))
{
inword = false;
}
}
average = (float) l_num / w_num;
printf("Characters: %-3d\n", l_num);
printf("Words num: %-3d\n", w_num);
printf("Average : %.2f\n", average);
return 0;
}
输出结果:
题目5,方法:二分查找猜数字。示例代码8_5.c:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>
void consumer(void); //清空缓冲区
bool character_check(void); //检测是否有非空字符并清空第一个非空字符及之前的缓冲区
char get_choice(void); //将选择输入限制在合法区间并返回输入值
int main(void)
{
char ch, ch1;
int min = 0, max = 100;
int num;
num = (min + max) / 2;
printf("I guess the number you choose is %d, right?\n", num);
while ((ch = get_choice()) != 'y')
{
printf("Is it bigger than %d?\n", num);
ch1 = get_choice();
if (ch1 == 'y')
min = num + 1;
else
max = num - 1;
num = (min + max) / 2;
printf("Well, I guess the number you choose is %d, right?\n", num);
}
printf("Game over!\n");
return 0;
}
void consumer(void)
{
while (getchar() != '\n')
continue;
}
bool character_check(void)
{
char ch2;
while ((ch2 = getchar()) != '\n') //第一个非空字符为回车,则读走回车
if (ch2 != '\t' && ch2 != ' ') //若第一个非空字符非回车,回车不被读走
return true;
//break; //结束函数,无需break
return false;
}
char get_choice(void)
{
char ch1;
printf("Enter a character to choose(y or n): ");
//防止第一个非空合法字符后出现第二个非空字符,例如assss
while (((ch1 = tolower(getchar())) != 'y' && ch1 != 'n') || character_check() == true)
{
if (ch1 == ' ' || ch1 == '\n' || ch1 == '\t') // 使至少第一个非空字符被ch1获得
continue;
else if (character_check() == true) //防止出现 fssss 这样的输入,即之前非法,之后合法,以及清空非空白字符缓冲区
{
consumer();
system("cls");
printf("Selection illeal, try again: ");
continue;
}
// 输入a2这样的输入时执行
system("cls");
printf("Selection illeal, try again: ");
}
return ch1;
}
输出结果:
题目6,方法:获取第一个非空白字符。示例代码8_6.c:
#include <stdio.h>
#include <ctype.h>
char get_choice(void);
char get_first(void);
int get_int(void);
void count(void);
int main(void)
{
int choice;
while ((choice = get_choice()) != 'q')
{
switch (choice)
{
case 'a': printf("Buy low, sell high.\n");
break;
case 'b': putchar('\a');
break;
case 'c': count();
break;
default: printf("Program error!\n");
break;
}
}
printf("Bye.\n");
}
void count(void)
{
int n, i;
printf("Count how far? Enter an integer: \n");
n = get_int();
for (i = 1; i <= n; i++)
printf("%d\n", i);
while (getchar() != '\n')
continue;
}
char get_choice(void)
{
int ch;
printf("Enter the letter of your choice: \n");
printf("a. advice b. bell\n");
printf("c. count q. quit.\n");
ch = get_first();
while ((ch < 'a' || ch > 'c') && ch != 'q')
{
printf("Please respond with a, b, c, or q.\n") ;
ch = get_first();
}
return ch;
}
char get_first(void)
{
int ch;
do
{
ch = getchar();
} while (isspace(ch)); //读取第一个非空白字符
while (getchar() != '\n')
continue;
return ch;
}
int get_int(void)
{
int input;
char ch;
while (scanf("%d", &input) != 1)
{
while ((ch = getchar()) != '\n')
putchar(ch); //发现错误读空缓冲区并输出
printf(" is not an integer.\nPlease enter an ") ;
printf("integer value, such as 25, -178, or 3: ");
}
return input;
}
输出结果:
题目7,方法:用字符代替数字选项。示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
#define RANK1 8.75f
#define RANK2 9.33f
#define RANK3 10.00f
#define RANK4 11.20f
#define OVERTIME 40
#define TIMES 1.5f
#define BASE1 300
#define BASE2 150
#define RAT_T1 0.15f
#define RAT_T2 0.20f
#define RAT_T3 0.25f
#define TAX1 (BASE1 * RAT_T1)
#define TAX2 (BASE2 * RAT_T2)
void show_menu(void); // 显示菜单
void caculate(char choo, float t); // 计算并打印结果
char choose_check(void); //将商品输入限制在合法区间并返回输入值
void consumer(void); // 一旦判断非法后立刻读空缓冲区,避免多次读取失败和多次打印提现信息
bool character_check(void); // 判断输入中除了数字和空白后面是否还有其它非法字符
int main(void)
{
char choose;
float work_h = 1;
while ((choose = choose_check()) != 'q')
{
system("cls") ;
show_menu();
printf("The selection you choose is %c.\n", choose);
printf("Please input your working hours (0 to back): ");
while (scanf("%f", &work_h) != 1 || work_h < 0 || character_check() == true)
{
consumer();
printf("Working hour input illegal, Try again: ");
}
if (work_h == 0)
{
system("cls");
continue;
}
caculate(choose, work_h);
}
printf("Done!\n");
return 0;
}
void show_menu(void)
{
printf("*****************************************************************\n");
printf("Enter the number corresponding to the desired pay rate or action:\n");
printf("a) $8.75/hr b)$9.33/hr\n");
printf("c) $10.00/hr d)$11.20/hr\n");
printf("q) quit\n");
}
void consumer(void)
{
while (getchar() != '\n')
continue;
}
bool character_check(void)
{
char ch;
while ((ch = getchar()) != '\n')
{
if (ch != '\t' && ch != ' ')
{
return true;
break;
}
}
return false;
}
char choose_check(void)
{
char ch1;
show_menu();
printf("Enter a character to choose: ");
//防止第一个非空合法字符后出现第二个非空字符,例如assss
while (((ch1 = tolower(getchar())) != 'a' && ch1 != 'b' && ch1 != 'c' && ch1 != 'd' && ch1 != 'q') || character_check() == true)
{
if (ch1 == ' ' || ch1 == '\n' || ch1 == '\t') // 使至少第一个非空字符被ch1获得
{
continue;
}
else if (character_check() == true) //防止出现 fssss 这样的输入,即之前非法,之后合法,以及清空非空白字符缓冲区
{
consumer();
system("cls");
show_menu();
printf("Menu selection illegal, Try again: ");
continue;
}
// 输入a2这样的输入时执行
system("cls");
show_menu();
printf("Menu selection illegal, Try again: ");
}
return ch1;
}
void caculate(char choo, float t)
{
float rank, total_in, tax, pure_in;
if (choo == 'a')
rank = RANK1;
else if (choo == 'b')
rank = RANK2;
else if (choo == 'c')
rank = RANK3;
else
rank = RANK4;
if (t > OVERTIME)
t += (t - OVERTIME) * TIMES;
total_in = rank * t;
if (total_in <= BASE1)
tax = total_in * RAT_T1;
else if (total_in <= (BASE1 + BASE2))
tax = TAX1 + (total_in - BASE1) * RAT_T2;
else
tax = TAX1 + TAX2 + (total_in - (BASE1 + BASE2)) * RAT_T3;
pure_in = total_in - tax;
printf("\nTotal income: %.2f\nTax: %.2f\nPure income: %.2f\n",
total_in, tax, pure_in);
printf("\nEnter to continue...");
consumer();
system("cls");
}
输出结果:
题目8,方法:简易的计算功能。示例代码:
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
void show_menu(void);
void consumer(int n1); //清空缓冲区
bool character_check(int n2); //检测是否有非空字符并清空第一个非空字符及之前的缓冲区
char choose_check(void); //将输入限制在合法区间并返回输入值
float float_check(void); //判断输入的浮点数是否合法
void add(float num1,float num2); //加法运算
void sub(float num1, float num2); //减法运算
void mult(float num1, float num2); //乘法运算
void divs(float num1, float num2); //除法运算
char str1[1000], str2[1000]; //统计输入字符
int k= 1, t = 0; //记录输入字符数
int main(void)
{
float a, b;
char ch;
a = b = 0;
while ((ch = choose_check()) != 'q')
{
switch (ch)
{
case 'a':
add(a, b);
break;
case 's':
sub(a, b);
break;
case 'm':
mult(a, b);
break;
case 'd':
divs(a, b);
break;
default:
printf("error.\n");
}
}
return 0;
}
void show_menu(void)
{
printf("****************************************\n");
printf("Please choose the operation:\n");
printf("a. add s. subtract\n");
printf("m. multiply d. divide\n");
printf("q. quit\n");
}
void consumer(int n1)
{
char cha;
while ((cha = getchar()) != '\n')
{
if (n1 == 1)
str1[k++] = cha;
else if (n1 == 2)
str2[t++] = cha;
}
}
bool character_check(int n2)
{
char ch2;
while ((ch2 = getchar()) != '\n') //第一个非空字符为回车,则读走回车
{
if (n2 == 1)
str1[k++] = ch2;
else if (n2 == 2)
str2[t++] = ch2;
if (ch2 != '\t' && ch2 != ' ') //若第一个非空字符非回车,回车不被读走
{
return true;
}
}
return false;
}
char choose_check(void)
{
char ch1;
show_menu();
printf("\nEnter a character to choose: ");
//防止第一个非空合法字符后出现第二个非空字符,例如assss
while (((ch1 = tolower(getchar())) != 'a' && ch1 != 's' && ch1 != 'm' && ch1 != 'd' && ch1 != 'q') || character_check(1) == true)
{
if (ch1 == ' ' || ch1 == '\n' || ch1 == '\t') // 使至少第一个非空字符被ch1获得
continue;
else if (character_check(1) == true) //防止出现 fssss 这样的输入,即之前非法,之后合法,以及清空非空白字符缓冲区
{
consumer(1);
system("cls");
show_menu();
putchar('\n');
str1[0] = ch1;
//或者printf("%s is illegal, try again: ", str1);
for (int i = 0; i < k; i++)
printf("%c", str1[i]);
printf(" is illegal, try again: ");
memset(str1, 0 ,sizeof(str1)); //初始化字符串数组
k = 1;
continue;
}
// 输入a2这样的输入时执行
system("cls");
show_menu();
putchar('\n');
str1[0] = ch1;
for (int i = 0; i < k; i++)
//或者putchar(str1[i]);
printf("%c", str1[i]);
printf(" is illegal, try again: ");
memset(str1, 0 ,sizeof(str1));
k = 1;
}
return ch1;
}
float float_check(void)
{
float number;
int judge, s;
//int len2, len3;
char str3[100];
char str4[100];
judge = 0;
s = 0;
while ((judge = scanf("%f", &number)) != 1 || character_check(2) == true)
{
consumer(2); //防止出现 gg12 这样的输入,即之前非法,之后合法
putchar('\n');
//方法一:移动字符串
// if (judge == 1)
// {
// sprintf(str3, "%g", number);
// len2 = strlen(str2);
// len3 = strlen(str3);
// for (i = len2 + len3 - 1; i > len3 - 1 ; i--)
// str2[i] = str2[--len2];
// for (i = 0; i < len3; i++)
// str2[i] = str3[i];
// }
// printf("%s is illegal, try again: ", str2);
//方法二:合并字符串
if (judge == 1)
{
sprintf(str3, "%g", number); //将number转换为字符串
for (int i = 0; i < (int) strlen(str3); i++) //若获取number成功,则存储number字符
str4[s++] = str3[i];
}
for (int i = 0; i < t; i++)
str4[s++] = str2[i];
printf("%s is illegal, try again: ", str4);
memset(str2, 0 ,sizeof(str2));
memset(str3, 0 ,sizeof(str3));
memset(str4, 0 ,sizeof(str4));
t = s = 0;
}
return number;
}
void add(float num1, float num2)
{
float sum;
printf("Please input first number: ");
num1 = float_check();
printf("Please input second number: ");
num2 = float_check();
sum = num1 + num2;
printf("%g + %g = %g\n", num1, num2, sum);
printf("Enter to continue...");
consumer(0);
system("cls");
}
void sub(float num1, float num2)
{
float subn;
printf("Please input first number: ");
num1 = float_check();
printf("Please input second number: ");
num2 = float_check();
subn = num1 - num2;
printf("%g - %g = %g\n", num1, num2, subn);
printf("Enter to continue...");
consumer(0);
system("cls");
}
void mult(float num1, float num2)
{
float mul;
printf("Please input first number: ");
num1 = float_check();
printf("Please input second number: ");
num2 = float_check();
mul = num1 * num2;
printf("%g * %g = %g\n", num1, num2, mul);
printf("Enter to continue...");
consumer(0);
system("cls");
}
void divs(float num1, float num2)
{
float divn;
printf("Please input first number: ");
num1 = float_check();
printf("Please input second number: ");
while ((num2 = float_check()) == 0)
{
printf("Please input a number other than 0: ");
}
divn = num1 / num2;
printf("%g / %g = %g\n", num1, num2, divn);
printf("Enter to continue...");
consumer(0);
system("cls");
}
输出结果: