编程环境Visual Studio 2017
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 |
#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; } |
此文为博主原创文章,转载请注明出处
第八题
开始输出选项以外的字符,都能进入下一条语句。
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 ;
}
你好,你这个 n_word == 0 ? 0 : (double)n_char / (double)n_word;为什么放到前面就不行呐,可以用if else给解释下吗 ,麻烦您了
你好楼主, 关于第八题对choice的判断,您写了
while (getchar() != '\n‘)
{
continue;
}
continue;
我有点疑惑,无论while是否为真,所执行的代码都是continue, 那为何不直接写一个continue呢?我是个新手,如果问了有哪里不对请多包涵。
你截取的代码中,第一个continue是跳过while循环的,这个while循环主要是去除输入缓冲区中的输入,第二个continue主要是跳过外部的do循环的,之后会让用户再进行输入选择
// practice 5
没有考虑选择的数字就是50 的情况吧,
问题搞错了,应该是 scanf_s("%c", &ch);应该提供一个数字以表明最多读取多少位字符;
改成 scanf_s("%c", &ch,1);不然会出差。