缓冲区 buffer
用户按下Enter键之前不会重复打印刚输入的字符,这种输入形式属于缓冲输入。
缓冲分两种:
- 完全缓冲I/O
当缓冲区被填满时才刷新缓冲区(内容被发送至目的地),通常出现在文件输入中。
缓冲区大小取决于系统,常见大小是512 byte
和4096 byte
。 - 行缓冲I/O
在出现换行符时才刷新缓冲区。键盘输入通常是行缓冲输入。在按下Enter后刷新缓冲区。
早先缓不缓冲是交给编译器决定的,后来从 ANSI C
开始默认都是使用缓冲区的。
8.11.1
/*
* @Author : TCP404
* @Description : 设计一个程序,统计在读到文件结尾之前读取的字符数。
* @version :
* @Date : 2020-04-21 14:45:14
* @LastEditors : TCP404
* @LastEditTime : 2020-04-21 15:31:40
*/
#include <stdio.h>
int main(void)
{
char ch = 0;
int count = 0;
printf("Enter some word, press <Ctrl+C> to exit.\n");
while ((ch = getchar()) != EOF)
if (ch != '\n')
count++;
printf("There are %d character", count);
return 0;
}
8.11.2
/*
* @Author : TCP404
* @Description : 编写一个程序,在遇到EOF之前,把输入作为字符流读取。程序要打印每个输入的字符及其响应的ASCII十进制的值。
* @version :
* @Date : 2020-04-21 15:41:09
* @LastEditors : TCP404
* @LastEditTime : 2020-04-21 16:11:11
*/
#include <stdio.h>
int main(void)
{
char ch = 0;
int tenCount = 0;
while ((ch = getchar()) != EOF)
{
++tenCount;
if (tenCount > 10)
{
putchar('\n');
tenCount = 0;
}
switch (ch)
{
case 10:
putchar('\\');
putchar('n');
printf(":10\t");
break;
case 9:
putchar('\\');
putchar('t');
printf(":09\t");
break;
case 32:
putchar('_');
printf(":32\t");
break;
default:
putchar(ch);
printf(":%d\t", ch);
break;
}
}
return 0;
}
8.11.3
/*
* @Author : TCP404
* @Description : 编写一个程序,在遇到EOF之前,把连续输入作为字符流读取。
* 该程序中要报告大写字母和小写字母的个数。
* 可以使用ctype.h库中合适的分类函数更方便。
* @version :
* @Date : 2020-04-21 16:14:03
* @LastEditors : TCP404
* @LastEditTime : 2020-04-21 16:25:10
*/
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char ch = 0;
int lowerCount = 0;
int supperCount = 0;
printf("\nPlease enter some things: \n");
while ((ch = getchar()) != EOF)
{
if (islower(ch))
lowerCount++;
else if (isupper(ch))
supperCount++;
}
printf("There has %d lower and %d supper.", lowerCount, supperCount);
return 0;
}
8.11.4
/*
* @Author : TCP404
* @Description : 编写一个程序,在遇到EOF之前,把输入作为字符流读取。该程序要报告平均每个单词的字母数。
* 不要把空白统计为单词的字母,标点符号也不要。
* @version :
* @Date : 2020-04-21 16:27:13
* @LastEditors : TCP404
* @LastEditTime : 2020-04-21 16:50:29
*/
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char ch = 0;
int count = 0;
printf("Please enter some word: \n");
while ((ch = getchar()) != EOF)
{
if (isalnum(ch))
{
putchar(ch);
count++;
}
if (ch == 32)
{
printf(":%d ", count);
count = 0;
}
}
return 0;
}
8.11.5
/*
* @Author : TCP404
* @Description : 修改8.4的猜数字程序,使用更智能的猜测策略,例如二分查找法。
* @version :
* @Date : 2020-04-21 16:52:02
* @LastEditors : TCP404
* @LastEditTime : 2020-04-21 18:27:10
*/
#include <stdio.h>
void find();
int main(void)
{
int guess = 100;
char ch = 0;
printf("Pick an integer from 1 to 100. I will try to guess it.\n");
printf("Respond with a \'y\' if my guess is right and with an \'n\' if it is wrong.\n");
printf("Un...is your number %d?\n", guess);
while ((ch = getchar()) != 'q')
if (ch == 'n')
{
find(guess);
}
else
{
printf("Awesome!!!");
break;
}
return 0;
}
void find(int guess)
{
char respond = 0;
int low = 0;
int heigh = guess;
while (low <= heigh)
{
int mid = (low + heigh) / 2;
printf("Well, then, is it %d\n", mid);
scanf("%c", &respond);
yes:
if (respond != 'y')
{
printf("More or Less ? [m/l]");
fflush(stdin);
scanf("%c", &respond);
switch (respond)
{
case 'm':
heigh = mid;
break;
case 'l':
low = mid;
break;
case 'y':
goto yes;
break;
default:
printf("Sorry, I understand only \'y\' , \'n\' , \'m\' and \'l\'.\n");
break;
}
}
else
{
printf("Awesome!!!");
break;
}
}
}
8.11.6
懒得写。
8.11.7
/*
* @Author : TCP404
* @Description : 改写第7章编程练习8,把菜单的1234改成abcd,用q退出替代5的退出。
* @version :
* @Date : 2020-04-21 21:28:39
* @LastEditors : TCP404
* @LastEditTime : 2020-04-21 21:36:37
*/
#include <stdio.h>
#define ST_WORK_TIME 40 //一周基本工时
#define ST_SALARY_WEEK i_choice * 40 //一周满40小时标准工薪
#define TAX1 d_salary * 0.15 //首300以内15%
#define TAX2 TAX1 + (d_salary - 300) * 0.2 //续150以内20%
#define TAX3 TAX1 + TAX2 + (d_salary - 450) * 0.25 //余下的25%
int main()
{
char i_choice; // i_选择:用来存放用户输入的时薪选项
int i_work_time; // i_工作时间:用来存放用户输入的一周工作时间
double d_salary; // d_薪资:用来存放 时间*时薪 的变量
double d_tax; // d_税率:用来存放用户应缴纳的税金
double d_net_income; // d_净收入:用来存放用户最后的净收入
a:
printf("********************************************************************\n");
printf("Enter the number corresponding to the desired pay rate or action ->\n\n");
printf("a) $8.75/h \t\t b)9.33/h \n");
printf("c) $10.0/h \t\t d)11.2/h \n");
printf("q) quit\n");
printf("********************************************************************\n");
printf("->");
fflush(stdin);
scanf("%c", &i_choice);
switch (i_choice)
{
case 97:
printf("Please enter your work hours a week:");
scanf("%d", &i_work_time);
break;
case 98:
printf("Please enter your work hours a week:");
scanf("%d", &i_work_time);
break;
case 99:
printf("Please enter your work hours a week:");
scanf("%d", &i_work_time);
break;
case 100:
printf("Please enter your work hours a week:");
scanf("%d", &i_work_time);
break;
case 113:
goto b;
break;
default:
printf("Please enter number in 1 ~ 5 ->\n");
goto a;
}
if (i_work_time <= 40)
{
d_salary = i_choice * i_work_time;
}
else
{
d_salary = ST_SALARY_WEEK + (i_work_time - ST_WORK_TIME) * i_choice * 1.5;
}
printf("\n\nYour salary is : \t$%.2f\n", d_salary);
//计算税率
if (d_salary <= 300)
{
d_tax = TAX1;
}
else if (d_salary <= 450)
{
d_tax = TAX2;
}
else
{
d_tax = TAX3;
}
printf("You need to pay taxes :\t $%.2f\n", d_tax);
d_net_income = d_salary - d_tax;
printf("Your net income is :\t $%.2f\n\n\n\n", d_net_income);
goto a;
b:
printf("\n\nSee you !\n");
return 0;
}
8.11.8
/*
* @Author : TCP404
* @Description : 写个程序,让用户选择加减乘除,先选,选错重新选,用float存要计算的数字,除法第二个不能为0,输错重新来
* @version :
* @Date : 2020-04-21 21:43:33
* @LastEditors : TCP404
* @LastEditTime : 2020-04-21 22:35:46
*/
#include <stdio.h>
enum BOOL
{
TRUE = 1,
FALSE = 0
};
void typeNum(enum BOOL divide);
float addition(float head, float end);
float subtraction(float head, float end);
float multiplication(float head, float end);
float division(float head, float end);
float head_num = 0;
float end_num = 0;
int main(void)
{
char i_choice = 0;
again:
printf("********************************************************************\n");
printf("Enter a/b/c/d to choice a way of compute, q to quit ->\n\n");
printf("a) + \t\t b) - \n");
printf("c) * \t\t d) / \n");
printf("q) quit\n");
printf("********************************************************************\n");
printf("->");
rechoice:
fflush(stdin);
scanf("%c", &i_choice);
switch (i_choice)
{
case 'a':
typeNum(FALSE);
printf("%.1f + %.1f = %.1f\n\n", head_num, end_num, addition(head_num, end_num));
break;
case 'b':
typeNum(FALSE);
printf("%.1f - %.1f = %.1f\n\n", head_num, end_num, subtraction(head_num, end_num));
break;
case 'c':
typeNum(FALSE);
printf("%.1f * %.1f = %.1f\n\n", head_num, end_num, multiplication(head_num, end_num));
break;
case 'd':
typeNum(TRUE);
printf("%.1f / %.1f = %.1f\n\n", head_num, end_num, division(head_num, end_num));
break;
case 'q':
goto quit;
break;
default:
printf("Input Error! Retype!\n");
goto rechoice;
break;
}
goto again;
quit:
printf("See you!");
return 0;
}
void typeNum(enum BOOL divide)
{
printf("Type the first number: ");
fflush(stdin);
while (scanf("%f", &head_num) != 1)
{
printf("Input Error!!! Retype!!!\n");
fflush(stdin);
}
re_sec_num:
printf("Type the second number: ");
fflush(stdin);
while (scanf("%f", &end_num) != 1)
{
printf("Input Error!!! Retype!!!\n");
fflush(stdin);
}
if (divide && end_num == 0)
{
printf("The denominator cannot be zero! Retype!\n");
goto re_sec_num;
}
}
float addition(float head, float end)
{
return head + end;
}
float subtraction(float head, float end)
{
return head - end;
}
float multiplication(float head, float end)
{
return head * end;
}
float division(float head, float end)
{
return end == 0 ? 0 : head / end;
}