Advertisements
Advertisements
Advertisements
编程环境Visual Studio 2017
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
// practice 1
void p8_1(void)
{
char ch = 0;
int n_char = 0;
while ((ch = getchar()) != EOF)
{
n_char++;
}
printf("There are %d characters in the file!\n", n_char);
return;
}
// practice 2
void p8_2(void)
{
char ch = 0;
int n_char = 0;
while ((ch = getchar()) != EOF)
{
n_char++;
if (ch < ' ')
{
if ('\t' == ch)
{
putchar('\\');
putchar('t');
printf(":%d ", ch);
}
else if ('\n' == ch)
{
putchar('\\');
putchar('n');
printf(":%d ", ch);
}
else
{
putchar('^');
putchar(ch+64);
printf(":%d ", ch);
}
}
else
{
putchar(ch);
printf(":%d ", ch);
}
if (n_char % 10 == 0)
{
printf("\n");
}
}
}
// practice 3
void p8_3(void)
{
char ch = 0;
int n_upper = 0;
int n_lower = 0;
while ((ch = getchar()) != EOF)
{
if (islower(ch))
{
n_lower++;
}
else if (isupper(ch))
{
n_upper++;
}
}
printf("There are %d upper character and %d lower charecter.\n", n_upper, n_lower);
return;
}
// practice 4
void p8_4(void)
{
char ch = 0;
char ch_pre = 0;
int n_word = 0;
int total_chr = 0;
int word_chr = 0;
double word_chr_avg = 0;
while (ch = getchar()) // 清除文件开头处的空格、标点和换行符等
{
if (isalpha(ch))
{
break;
}
}
while (ch != EOF)
{
// 排除连续空格、换行、连续标点符号等情况
if ((' ' == ch || '\n' == ch) && !isspace(ch_pre) && !ispunct(ch_pre))
{
n_word++;
printf("ch_pre = %c\n", ch_pre);
total_chr += word_chr;
printf("word_chr = %d, total_chr = %d\n", word_chr, total_chr);
word_chr = 0;
}
else if (isspace(ch)) // 清除连续的空格
{
ch_pre = ch;
ch = getchar();
continue;
}
if (!ispunct(ch) && !isspace(ch))
{
word_chr++;
}
ch_pre = ch;
ch = getchar();
}
if (!isspace(ch_pre))
{
n_word++;
printf("ch_pre = %c\n", ch_pre);
total_chr += word_chr;
}
word_chr_avg = (double)total_chr / n_word;
printf("Total words: %d, Total characters: %d, Characters per word: %.2lf", n_word, total_chr, word_chr_avg);
}
// practice 5
void p8_5(void)
{
char ch = 0;
int upper = 100;
int lower = 0;
int guest = 50;
printf("I guest the number is 50. Is it right(Y/N)?");
scanf_s("%c", &ch);
getchar();
while ('Y' != ch)
{
printf("Ok, the number you chosen is bigger or smaller than I guest?(B/S)");
scanf_s("%c", &ch);
getchar();
if ('B' == ch)
{
lower = guest;
guest = (lower + upper) / 2;
}
else
{
upper = guest;
guest = (lower + upper) / 2;
}
printf("I guest the number is %d, Is it right(Y/N)?", guest);
scanf_s("%c", &ch);
getchar();
}
printf("HAHA, I win!");
return;
}
// practice 6
char get_first(void)
{
int ch = 0;
while (!isalpha(ch = getchar()))
{
continue;
}
return ch;
}
void p8_6(void)
{
char ch = get_first();
putchar(ch);
}
// practice 7
#define RATE1 0.15
#define RATE2 0.20
#define RATE3 0.25
void p8_7(void)
{
char chooice = 0;
double work_hours = 0;
double total_income = 0;
double tax = 0;
double net_income = 0;
double hourly_wage = 0;
while (1)
{
printf("Enter the number corresponding to the desired pay rate to action:\n");
printf("%-20s%-20s\n%-20s%-20s\n%-20s\n", "a) $8.75/hr", "b) $9.33/hr", "c) $10.00/hr", "d) $11.20/hr", "q) quit");
scanf_s("%c", &chooice);
getchar();
switch (chooice)
{
case 'a':
hourly_wage = 8.75;
break;
case 'b':
hourly_wage = 9.33;
break;
case 'c':
hourly_wage = 10.00;
break;
case 'd':
hourly_wage = 11.20;
break;
case 'q':
return;
default:
printf("Please enter the choice between a to d and q\n");
continue;
}
printf("How long have you worked:");
scanf_s("%lf", &work_hours);
getchar();
if (work_hours > 40)
{
work_hours = (work_hours - 40) * 1.5 + 40;
}
total_income = work_hours * hourly_wage;
if (total_income <= 300)
{
tax = total_income * RATE1;
net_income = total_income - tax;
}
else if (300 < total_income <= 450)
{
tax = 300 * RATE1 + (total_income - 300) * RATE2;
net_income = total_income - tax;
}
else
{
tax = 300 * RATE1 + 150 * RATE2 + (total_income - 450) * RATE3;
net_income = total_income - tax;
}
printf("total income = %.2lf, tax = %.2lf, net income = %.2lf\n", total_income, tax, net_income);
}
return;
}
// practice 8
// 浮点数无法和0.0进行"=="判断,设置一个判断阀值
#define ABS_VAL 0.000001
void p8_8(void)
{
float number1 = 0.0;
float number2 = 0.0;
char choice = 0;
do
{
printf("Enter the operation of your choice:\n");
printf("%-20s%-20s\n%-20s%-20s\n%-20s\n", "a. add", "s. subtract", "m. multuply", "d. divide", "q. quit");
// 如果scanf的返回值为1并且输入值是a、s、m、d、q中之一代表输入成功,这里取反剔除不符合条件的输入
if (!(scanf("%c", &choice) == 1 && (('a' == choice) || ('s' == choice) || ('m' == choice) || ('d' == choice) || ('q' == choice))))
{
printf("Please enter the correct operation, please enter again!\n");
while (getchar() != '\n')
{
continue;
}
continue;
}
getchar();
if ('q' == choice)
{
printf("Bye!\n");
return;
}
printf("Enter first number:");
while (scanf_s("%f", &number1) != 1)
{
char ch = 0;
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: ");
}
getchar();
printf("Enter second number:");
while (scanf_s("%f", &number2) != 1)
{
char ch = 0;
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: ");
}
getchar();
switch (choice)
{
case 'a':
printf("%f + %f = %f\n", number1, number2, (number1 + number2));
break;
case 's':
printf("%f - %f = %f\n", number1, number2, (number1 - number2));
break;
case 'm':
printf("%f * %f = %f\n", number1, number2, (number1 * number2));
break;
case 'd':
//在阈值区间内,将输入值判断为零,要求重新输入
while (number2 > -ABS_VAL && number2 < ABS_VAL)
{
printf("Enter a number other than 0:");
while (scanf_s("%f", &number2) != 1)
{
char ch = 0;
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: ");
}
getchar();
}
printf("%f / %f = %f\n", number1, number2, (number1 / number2));
break;
default:
break;
}
} while (1);
return;
}
int main(int argc, char **argv)
{
p8_8();
while (getchar());
return 0;
}
此文为博主原创文章,转载请注明出处
Advertisements
Advertisements
Advertisements
第八题
开始输出选项以外的字符,都能进入下一条语句。
Thanks!有个逻辑判断没写对,已经改好了
楼主,Practice 4 中 这个判断条件 if ((' ' == ch || '\n' == ch) && !isspace(ch_pre))
若果输入 an , , , (字符后面跟空格和逗号)单词总数就增加。觉得在原有基础上加一个条件 if((' ' == ch || '\n' == ch) && !isspace(ch_pre) && !ispunct(ch_pre))
是的,这里是我考虑不够周全,加上这个判断会更好
楼主第4题的ch_pre是什么意思
记录前一个字符内容,用来判断连续空格使用的
楼主你好,我现在也在做第八章的习题,关于第2题,我和您答案基本相同,但是题目中说“每次遇到换行符打印新的一行”,我理解的意思是程序允许输入多行,而不是在按下回车后就显示结果,应该是在按下Ctrl+D后才显示结果,所以感觉咱们的答案都不符合题意,但我水平有限,不知如何改正,望能得到您的答复,若我有表述不清的地方,还请您和我一同讨论,感谢您的博客,对我学习这本书有很大帮助。
因为书不在身边,所以具体意思我这边暂时看不了了,那就先按照你的意思来理解。如果要做到按下Ctrl-D后才显示的话,一方面控制台要通过系统函数来直接获取到键盘的输入值,否则输入值都是会缓存在输入缓冲区的;其次就是通过char数组将所有的输入值缓存起来了,下面是我按照这个要求写的程序,与你交流:
怎么贴代码啊?
https://blog.csdn.net/weixin_43481677/article/details/83245561 楼主 这是我自己写的书上第八章程序清单8.8 的链接 但是运行起来和书上不一样,我输入a 的时候 这个程序不打印case a 的内容 ,不知道哪里出问题了 麻烦有空帮忙看下
你的main函数while循环后面多了个分号啊,自己好好检查一下。另外你打印的信息显示退出条件是输入d,但是你判断的条件是输入q,这里也不太对
谢谢楼主 按照你的指正 修改好 运行起来就和书上一样了
https://blog.csdn.net/weixin_43481677/article/details/83377919 第八章习题 有好几处问题,评论框太小了,装不下,麻烦楼主点看链接 解答下 谢谢
第4题我找到了一个简单的方法,可以模仿书上的程序 7.7 第195页的题目
#include
#include
int main(void)
{
int lisd;
lisd = 0;
char ch;
bool kad = false;
while ((ch = getchar()) != EOF)
{
if (!isspace(ch) && !kad && !ispunct(ch))
{
kad = true;
lisd++;
}
if ((isspace(ch) && kad)||ispunct(ch))
{
kad = false;
}
putchar(ch);
}
printf("单词数为 %d 个", lisd);
}
同时解决了标点符号问题
头文件用了 ctype.h
差不多啊大兄弟,书上7.7还统计了字符数和行数
楼主您好,第四题的解法似乎未处理“ch 为字母且 ch_pre 为标点”的情形,输入流中有标点紧跟的单词不被计入总词数。文本“Yes!”测试返回 0 单词、0 字母、-NaN 字母/词。
第五题优化了一下 这个可以有输入验证了 但不知道会不会啰嗦了一点
#include
int main()
{
char ch = 0;
int upper = 100;
int lower = 0;
int guest = 50;
printf("I guest the number is 50. Is it right(Y/N)?");
scanf("%c", &ch);
getchar();
while ('Y' != ch)
{
if ('N' == ch)
{
printf("Ok, the number you chosen is bigger or smaller than I guest?(B/S) : ");
scanf("%c", &ch);
getchar();
if ('B' == ch)
{
lower = guest;
guest = (lower + upper) / 2;
}
else if ('S' == ch)
{
upper = guest;
guest = (lower + upper) / 2;
}
else
{
printf("ATTENTION ! Sorry I can only understand B/S. Please enter again \n");
continue;
}
printf("I guest the number is %d, Is it right(Y/N)?", guest);
scanf("%c", &ch);
getchar();
continue;
}
if ('N' != ch)
{
printf("Is it %d? Please enter again: (Y/N)", guest);
scanf("%c", &ch);
getchar();
continue;
}
}
printf("It is %d. HAHA, I win!", guest);
return 0;
}
/*
* 通过前一个字符和当前字符判断是否是一个单词有三种情况
* no prev current result action
* 1 0 1 单词开始 n_char++
* 2 1 1 单词中 n_char++
* 3 1 0 单词结束 n_word++
*
* 而在只计算字符总数, 和单词总数的情况下情况1和情况2就简化,合并为一条语句,即只判断
* 当前字符是不是字母即可.
* 而在当前字符不是字母的情况下,前一个字符只有两种情况是或不是,如果是表示单词结束,
* 如果不是,表示还未接收到单词. 当前题目下只需要对是的情况作出动作即可.
* 所以第二个条件和简化后的第一个条件再次简化,合并为一条 if..else if.. 语句
*/
# include
# include
int main(void)
{
int prev ; // 前一个字符
int ch ; // 当前字符
long n_char = 0 ; // 字符数量
long n_word = 0 ; // 单词数量
while ((ch = getchar()) != EOF)
{
if (isalpha(ch))
n_char++ ;
else if (isalpha(prev))
n_word++ ;
prev = ch ;
}
printf("Total words: %ld , Total characters: %ld , Characters per word:%.2lf",
n_word , n_char , n_word == 0 ? 0.0 :(double)n_char / (double)n_word);
return 0 ;
}
贴出来的样子都变了
___________________________________
no prev current result action
....
...
____________________________________
这一段是一个制表符对齐的真值表
我用语言描述一下
情况1: 前一个字符 不是字母 , 当前字符 是字母 ; 认为单词开始 , 字符数+1
情况2:前一个字符 是字母 , 当前字符 是字母; 认为在单词中, 字符数+1
情况3:前一个字符 是字母 , 当前字符 不是字符; 认为单词结束, 单词数+1
还有后面的 笑脸我也是醉了, 我在重新贴一次代码
/*第四题:编写一个程序,在遇到EOF之前,把输入作为字符流读取,该程序要报告平均每个单词的字母数,不要把空白统计为单词的字母.实际上标点符号也不应该统计,但时现在暂时不用考虑这么多(如果你比较在意这点,考虑使用ctype.h 系列中的ispunct()函数).
* 通过前一个字符和当前字符判断是否是一个单词有三种情况
* no prev current result action
* 1 0 1 单词开始 n_char++
* 2 1 1 单词中 n_char++
* 3 1 0 单词结束 n_word++
*
* 而在只计算字符总数, 和单词总数的情况下情况1和情况2就简化,合并为一条语句,即只判断
* 当前字符是不是字母即可.
* 而在当前字符不是字母的情况下,前一个字符只有两种情况是或不是,如果是表示单词结束,
* 如果不是,表示还未接收到单词. 当前题目下只需要对是的情况作出动作即可.
* 所以第二个条件和简化后的第一个条件再次简化,合并为一条 if..else if.. 语句
*/
# include
# include
int main(void)
{
int prev ; // 前一个字符
int ch ; // 当前字符
long n_char = 0 ; // 字符数量
long n_word = 0 ; // 单词数量
while ((ch = getchar()) != EOF)
{
if (isalpha(ch))
n_char++ ;
else if (isalpha(prev))
n_word++ ;
prev = ch ;
}
printf("Total words: %ld , Total characters: %ld , Characters per word:%.2lf",
n_word , n_char , n_word == 0 ? 0 : (double)n_char / (double)n_word);
return 0 ;
}
你好楼主, 关于第八题对choice的判断,您写了
while (getchar() != '\n‘)
{
continue;
}
continue;
我有点疑惑,无论while是否为真,所执行的代码都是continue, 那为何不直接写一个continue呢?我是个新手,如果问了有哪里不对请多包涵。
你截取的代码中,第一个continue是跳过while循环的,这个while循环主要是去除输入缓冲区中的输入,第二个continue主要是跳过外部的do循环的,之后会让用户再进行输入选择