C_Primer_Plus07.Branch

控制语句:分支和跳转

  • 要点

if, else, switch, continue, break, case, default, goto
&&, ||, ?
getchar(), putchar(), ctype.h
if, if-else
C 的条件运算符 a? b:c
switch 语句
break, continue 和 goto 语句
使用 C 的字符 I/O 函数: getchar()putchar()
ctype.h 头文件提供的字符分析函数

if 语句

getchar()putchar()

getchar(): 从输入队列中返回一个字符
putchar(): 打印它的参数(字符类型)

由于这些函数只处理字符,所以他们比更通用的 scanf() 和 printf() 函数更快、更简洁。
它们通常都定义在 stdio.h 头文件中,而且他们通常是预处理宏,而不是真正的函数。

#include <stdio.h>
#define SPACE ' '

int main(void){
    char ch;

    while ((ch = getchar()) != '\n'){
        if (ch == SPACE)
            putchar(ch);        // 空格不变
        else
            putchar(ch + 1);    // 改变其他字符
    }
    putchar(ch);

    return 0;
}

output:

hello world!
ifmmp xpsme"

ctype.h

C 中专门用来处理字符的函数。包含了这些函数的原型,这些函数接受一个字符作为参数,判断字符是否属于某特殊类别。

isalpha(ch);  // 判断ch是否是一个字母,如果是,返回一个非零值
  • ctype.h 头文件中的字符测试函数:
函数名 判断条件,满足则返回真
isalnum() 字母或数字
isalpha() 字母
isblank() 标准空白字符(空格、水平制表符,换行符)或本地化指定为空白的字符
iscntrl() 控制字符(ctrl)
isdigit() 数字
isgraph() 空格之外的任意可打印字符
islower() 小写字母
isprint() 可打印字符
ispunct() 标点符号
isspace() 空白字符(空格、换行符、制表符、回车、换页等)
isupper() 大写字母
isxdigit() 十六进制数字字符
  • ctype.h 头文件中的字符映射函数:
函数名 作用
tolower() 返回小写字符
toupper() 返回大写字符

多层嵌套

求素数:

#include <stdio.h>
#include <stdbool.h>

int main(void){
    unsigned long num, div;
    bool isPrime;  // bool 类型来自 stdbool.h 头文件

    printf("Please enter an integer for analysis; "
            "Enter q to quit.\n");
    while (1 == scanf("%lu", &num)){
        for (div = 2, isPrime = true; (div*div) <= num; div++){
            if (0 == (num % div)){
                printf("%lu is divided by %lu.\n", num, div);
                isPrime = false;
                break;
            }
        }
        if (isPrime)
            printf("%lu is a prime.\n", num);
        printf("Please enter another integer for analysis; "
                "Enter q to quit.\n");
    }

    return 0;
}

output:

Please enter an integer for analysis; Enter q to quit.
4
4 is divided by 2.
Please enter another integer for analysis; Enter q to quit.
5
5 is a prime.
Please enter another integer for analysis; Enter q to quit.
6
6 is divided by 2.
Please enter another integer for analysis; Enter q to quit.
d

逻辑运算符

&&, ||, ! (与或非)
非的优先级很高,高于乘法,低于圆括号,&& 比 || 高,&& 和 || 都小于比较运算符:

a > b && b > c || b > d
// 等价于:
((a > b) && (b > c)) || (b > d)

iso646.h 头文件

C 语言是用美式键盘开发的语言,有些地方不支持特殊符号。C99 标准新增了可替代逻辑运算符的方法,包含在 iso646.h 头文件中,可用 and,or 和 not 代替 &&, || 和 !

统计单词:

#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
#define END_CHAR '|'

// 循环读一个字符
//   字符数计数
//   如果是单词结束,单词数计数
//   如果是换行符,行数计数
//   如果是结束标志,结束循环
int main(void){
    char in_char;
    char prev = END_CHAR;
    unsigned int cnt_char = 0;
    unsigned int cnt_word = 0;
    unsigned int cnt_line = 0;
    bool inword = false;
    bool is_word = false;

    printf("Input anything (%c to quit):\n", END_CHAR);
    while (END_CHAR != (in_char = getchar())){
        cnt_char++;
        is_word = !(isspace(in_char) || ispunct(in_char));
        if (inword && !is_word){
            cnt_word++;
            inword = false;
        }
        inword = is_word;
        if ('\n' == in_char){
            cnt_line++;
        }
        prev = in_char;
    }
    if (inword)
        cnt_word++;
    if ('\n' != prev)
        cnt_line++;

    printf("Input end.\n"
            "count chars: %u\n"
            "count words: %u\n"
            "count lines: %u.\n", cnt_char, cnt_word, cnt_line);

    return 0;
}

output:

Input anything (| to quit):
hello world! This
is china.
welcome to china|
Input end.
count chars: 45
count words: 8
count lines: 3.

continue 和 break

switch-case-break

适合分类有限的情况,且不能用于浮点数。生成的代码比 if-else 少,运行速度稍快。

goto

谨慎使用,甚至不用


ex01:
1.编写一个程序读取输入,读到#字符停止,然后报告读取的空格数、换行符数和所有其他字符的数量。

/* statistic characters */
#include <stdio.h>

int main(void){
    char in_char;
    char prev = '\n';
    unsigned int num_space = 0;
    unsigned int num_lines = 0;
    unsigned int num_otherchar = 0;

    printf("Enter anything (# to quit):\n");
    while ('#' != (in_char = getchar())){
        switch (in_char){
            case ' ':
                ++num_space;
                break;
            case '\n':
                ++num_lines;
                break;
            default:
                ++num_otherchar;
                break;
        }
        prev = in_char;
    }
    if ('\n' != prev){
        ++num_lines;
    }
    printf("space: %u, lines: %u, otherchar: %u\n", num_space, num_lines, num_otherchar);

    return 0;
}

output:

Enter anything (# to quit):
hello world !

3rd line..
#
space: 3, lines: 3, otherchar: 20

ex02:
编写一个程序读取输入,读到#字符停止。程序要打印每个输入的字符以及对应的ASCII码(十进制)。一行打印8个字符。建议:使用字符计数和求模运算符(%)在每8个循环周期时打印一个换行符。

/* print ascii */
#include <stdio.h>

int main(void){
    char in_char;
    int period = 8;
    int i = 0;

    printf("Enter anything (# to quit):\n");
    while ('#' != (in_char = getchar())){
        if ('\n' == in_char){
            printf("\n");
            i = 0;
            continue;
        }
        printf("    %c:0x%x", in_char, in_char);
        if (0 == (++i % 8)){
            printf("\n");
        }
    }   
    printf("\n");

    return 0;
}

output:

Enter anything (# to quit):
Hellow Newton! This is world.
    H:0x48    e:0x65    l:0x6c    l:0x6c    o:0x6f    w:0x77     :0x20    N:0x4e
    e:0x65    w:0x77    t:0x74    o:0x6f    n:0x6e    !:0x21     :0x20    T:0x54
    h:0x68    i:0x69    s:0x73     :0x20    i:0x69    s:0x73     :0x20    w:0x77
    o:0x6f    r:0x72    l:0x6c    d:0x64    .:0x2e
Hello world! This is Newton.
    H:0x48    e:0x65    l:0x6c    l:0x6c    o:0x6f     :0x20    w:0x77    o:0x6f
    r:0x72    l:0x6c    d:0x64    �:0xffffffef    �:0xffffffbc    �:0xffffff81     :0x20    T:0x54
    h:0x68    i:0x69    s:0x73     :0x20    i:0x69    s:0x73     :0x20    N:0x4e
    e:0x65    w:0x77    t:0x74    o:0x6f    n:0x6e    .:0x2e
abcd#
    a:0x61    b:0x62    c:0x63    d:0x64

ex03:
编写一个程序,读取整数直到用户输入 0。输入结束后,程序应报告用户输入的偶数(不包括 0)个数、这些偶数的平均值、输入的奇数个数及其奇数的平均值。

#include <stdio.h>

int main(void){
    int size = 255;
    int in_int;
    int odd_int[size];
    int even_int[size];
    double sum_odd = 0.;
    double sum_even = 0.;
    int num_odd = 0;
    int num_even = 0;

    do {
        printf("Enter an integer: ");
        scanf("%d", &in_int);
        if (0 == (in_int % 2)){
            odd_int[num_odd++] = in_int;
            sum_odd += in_int;
        }else{
            even_int[num_even++] = in_int;
            sum_even += in_int;
        }
    } while (0 != in_int);

    printf("%d odd number, %d even number;\n", num_odd, num_even);
    printf("average odd: %.3f, average even: %.3f\n", sum_odd / num_odd, sum_even / num_even);

    return 0;
}

output:

Enter an integer: 34
Enter an integer: 45
Enter an integer: 897
Enter an integer: 45
Enter an integer: 23
Enter an integer: 1
Enter an integer: 8
Enter an integer: 67
Enter an integer:
94
Enter an integer: 0
4 odd number, 6 even number;
average odd: 34.000, average even: 179.667

ex04:
使用if else语句编写一个程序读取输入,读到#停止。用感叹号替换句号,用两个感叹号替换原来的感叹号,最后报告进行了多少次替换。

/* replace . with !, !! with ! */
#include <stdio.h>

int main(void){
    char in_char;
    int replace = 0;

    printf("Enter anything (# to quit):\n");
    while ('#' != (in_char = getchar())){
        if ('.' == in_char){
            printf("!");
            ++replace;
        }else if('!' == in_char){
            printf("!!");
            ++replace;
        }else{
            printf("%c", in_char);
        }
    }
    printf("\nReplacement occurs %d times.\n", replace);

    return 0;
}

output:

Enter anything (# to quit):
lfasdj.dfa!.
lfasdj!dfa!!!
!
!!
adf..#
adf!!
Replacement occurs 6 times.

ex06:
编写程序读取输入,读到#停止,报告ei出现的次数。
注意:该程序要记录前一个字符和当前字符。用“Receive your eieio award”这样的输入来测试。

/* find substring with kmp algorithm */
#include <stdio.h>
#include <string.h>

int main(void){
    char in_char;
    char mchars[] = "ei";
    int len = strlen(mchars);
    int pt = 0;
    int count = 0;
    int next[len];

    // next
    if (0 < len){
        next[0] = -1;
    }
    if (1 < len){
        if (mchars[1] == mchars[0]){
            next[1] = -1;
        }else{
            next[1] = 0;
        }
        for (int i = 2, j, k; i < len; ++i){
            for (k = i - 2; -1 < k; --k){
                if (mchars[k] == mchars[i-1] && mchars[k+1] != mchars[i]){
                    for (j = 0;
                            j < k && mchars[j] == mchars[i-k+j-1];
                            ++j){
                    }
                    if (j == k && 0 < k){
                        break;
                    }
                }
            }
            if (-1 == k){
                if (mchars[0] == mchars[i]){
                    next[i] = -1;
                }else{
                    next[i] = 0;
                }
            }else{
                next[i] = k + 1;
            }
        }
    }
    printf("next:");
    for (int i = 0; i < len; ++i){
        printf("  %c:%d", mchars[i], next[i]);
    }
    printf("\n\n");

    printf("This program aims to find '%s' from input.\n", mchars);
    printf("Enter anything (# to quit):\n");
    while ('#' != (in_char = getchar())){
        while (-1 < pt && mchars[pt] != in_char){
            pt = next[pt];
        }
        ++pt;
        if (pt == len){
            ++count;
            pt = 0;
        }
    }
    printf("Total %d times '%s' appeared in your input.\n", count, mchars);

    return 0;
}

output:

This program aims to find 'ei' from input.
Enter anything (# to quit):
eieieieieieieieieiieiei
#
Total 11 times 'ei' appeared in your input.

########## another:
This program aims to find 'ei' from input.
Enter anything (# to quit):
e
i#
Total 0 times 'ei' appeared in your input.


########## find abcdabcdabce
next:  a:-1  b:0  c:0  d:0  a:-1  b:0  c:0  d:0  a:-1  b:0  c:0  e:7

This program aims to find 'abcdabcdabce' from input.
Enter anything (# to quit):
abcdabcdabcdabcdabceabc#
Total 1 times 'abcdabcdabce' appeared in your input.

另一种写法:

/* find substring with kmp algorithm */
#include <stdio.h>
#include <string.h>

int main(void){
    char in_char;
    //char mchars[] = "ei";
    char mchars[] = "abcabcdabce";
    int len = strlen(mchars);
    int pt = 0;
    int count = 0;
    int next[len];

    // next
    int i = 0;
    int j = -1;
    next[i] = j;
    while (i < len){
        if (-1 == j || mchars[i] == mchars[j]){
            ++i;
            ++j;
            if (mchars[i] == mchars[j]){
                next[i] = next[j];
            }else{
                next[i] = j;
            }
        }else{
            j = next[j];
        }
    }
    printf("next:");
    for (int i = 0; i < len; ++i){
        printf("  %c:%d", mchars[i], next[i]);
    }
    printf("\n\n");

    printf("This program aims to find '%s' from input.\n", mchars);
    printf("Enter anything (# to quit):\n");
    while ('#' != (in_char = getchar())){
        while (-1 < pt && mchars[pt] != in_char){
            pt = next[pt];
        }
        ++pt;
        if (pt == len){
            ++count;
            pt = 0;
        }
    }
    printf("Total %d times '%s' appeared in your input.\n", count, mchars);

    return 0;
}

output:

next:  a:-1  b:0  c:0  a:-1  b:0  c:0  d:3  a:-1  b:0  c:0  e:3

This program aims to find 'abcabcdabce' from input.
Enter anything (# to quit):
abcabcabcdabce#
Total 1 times 'abcabcdabce' appeared in your input.

ex07:
编写一个程序,提示用户输入一周工作的小时数,然后打印工资总额、税金和净收入。做如下假设:

a.基本工资 = 1000美元/小时
b.加班(超过40小时) = 1.5倍的时间
c.税率: 前300美元为15%
续150美元为20%
余下的为25%

用#define定义符号常量。不用在意是否符合当前的税法。

/* calculate tax */
#include <stdio.h>
#define HOUR           40    // basic hour per week
#define SALARY         10.   // basic salary
#define OVERTIME_RATE  1.5   // overtime rate
#define TAX_SALARY0    300   // salary for tax rate0
#define TAX_RATE0      0.15  // tax rate0
#define TAX_SALARY1    150   // salary for tax rate1
#define TAX_RATE1      0.2   // tax rate1
#define TAX_RATE2      0.25  // tax rate2

int main(void){
    int hours;
    double tax;
    double salary;
    double real_salary;

    printf("Input hours: ");
    while (0 != scanf("%d", &hours)){
        salary = hours * SALARY;
        if (HOUR < hours){
            salary += (OVERTIME_RATE - 1.) * (hours - HOUR);
        }
        tax = salary * TAX_RATE0;
        if (TAX_SALARY0 < salary){
            tax += (TAX_RATE1 - TAX_RATE0) * (salary - TAX_SALARY0);
        }
        if (TAX_SALARY1 < (salary - TAX_SALARY0)){
            tax += (TAX_RATE2 - TAX_RATE1) * (salary - TAX_SALARY0 - TAX_SALARY1);
        }
        real_salary = salary - tax;
        printf("hours: %d; salary: %.2lf; tax: %.2lf; real_salary: %.2lf\n",
                hours, salary, tax, real_salary);
        printf("Continue input hours: ");
    }
    printf("Exit.\n");

    return 0;
}

output:

Input hours: 10
hours: 10; salary: 100.00; tax: 15.00; real_salary: 85.00
Continue input hours: 20
hours: 20; salary: 200.00; tax: 30.00; real_salary: 170.00
Continue input hours: 30
hours: 30; salary: 300.00; tax: 45.00; real_salary: 255.00
Continue input hours: 40
hours: 40; salary: 400.00; tax: 65.00; real_salary: 335.00
Continue input hours: 50
hours: 50; salary: 505.00; tax: 88.75; real_salary: 416.25
Continue input hours: 60
hours: 60; salary: 610.00; tax: 115.00; real_salary: 495.00
Continue input hours: 70
hours: 70; salary: 715.00; tax: 141.25; real_salary: 573.75
Continue input hours: 80
hours: 80; salary: 820.00; tax: 167.50; real_salary: 652.50
Continue input hours: 90
hours: 90; salary: 925.00; tax: 193.75; real_salary: 731.25
Continue input hours: 100
hours: 100; salary: 1030.00; tax: 220.00; real_salary: 810.00
Continue input hours: q
Exit.

ex08:
修改练习7的假设a,让程序可以给出一个供选择的工资等级菜单。使用switch完成工资等级选择。运行程序后,显示的菜单应该类似这样:


Enter the number corresponding to the desired pay rate or action:
1) $8.75/hr              2) $9.33/hr
3) $10.00/hr             4) $11.20/hr
5) quit

如果选择 1~4 其中的一个数字,程序应该询问用户工作的小时数。程序要通过循环运行,除非用户输入 5。如果输入 1~5 以外的数字,程序应提醒用户输入正确的选项,然后再重复显示菜单提示用户输入。使用#define创建符号常量表示各工资等级和税率。

/* calculate tax */
#include <stdio.h>
#define HOUR           40    // basic hour per week
#define OVERTIME_RATE  1.5   // overtime rate
#define TAX_SALARY0    300   // salary for tax rate0
#define TAX_RATE0      0.15  // tax rate0
#define TAX_SALARY1    150   // salary for tax rate1
#define TAX_RATE1      0.2   // tax rate1
#define TAX_RATE2      0.25  // tax rate2

int main(void){
    double basic_salary;
    int select;
    int hours;
    double tax;
    double salary;
    double real_salary;

    printf("Enter the number corresponding to the desired pay rate or action:\n");
    printf("1)  $ 8.75/hr        2)  $ 9.33/hr\n"
            "3)  $ 10.00/hr       4)  $ 11.20/hr\n"
            "5)  quit\n");
    if (0 == scanf("%d", &select) || select < 1 || select > 5){
        printf("Invalid input, program exit.\n");
        return 0;
    }
    switch (select){
        case 1:
            basic_salary = 8.75;
            break;
        case 2:
            basic_salary = 9.33;
            break;
        case 3:
            basic_salary = 10.00;
            break;
        case 4:
            basic_salary = 11.20;
            break;
        default:
            printf("You select to quit.\n");
            return 0;
    }
    printf("You select $ %.2f/hr.\n", basic_salary);

    printf("Input hours: ");
    while (0 != scanf("%d", &hours)){
        salary = hours * basic_salary;
        if (HOUR < hours){
            salary += (OVERTIME_RATE - 1.) * (hours - HOUR);
        }
        tax = salary * TAX_RATE0;
        if (TAX_SALARY0 < salary){
            tax += (TAX_RATE1 - TAX_RATE0) * (salary - TAX_SALARY0);
        }
        if (TAX_SALARY1 < (salary - TAX_SALARY0)){
            tax += (TAX_RATE2 - TAX_RATE1) * (salary - TAX_SALARY0 - TAX_SALARY1);
        }
        real_salary = salary - tax;
        printf("hours: %d; salary: %.2lf; tax: %.2lf; real_salary: %.2lf\n",
                hours, salary, tax, real_salary);
        printf("Continue input hours: ");
    }
    printf("Exit.\n");

    return 0;
}

output:

Enter the number corresponding to the desired pay rate or action:
1)  $ 8.75/hr        2)  $ 9.33/hr
3)  $ 10.00/hr       4)  $ 11.20/hr
5)  quit
5
You select to quit.
////////////////////
Enter the number corresponding to the desired pay rate or action:
1)  $ 8.75/hr        2)  $ 9.33/hr
3)  $ 10.00/hr       4)  $ 11.20/hr
5)  quit
q
Invalid input, program exit.
/////////////////
Enter the number corresponding to the desired pay rate or action:
1)  $ 8.75/hr        2)  $ 9.33/hr
3)  $ 10.00/hr       4)  $ 11.20/hr
5)  quit
4
You select $ 11.20/hr.
Input hours: 50
hours: 50; salary: 565.00; tax: 103.75; real_salary: 461.25
Continue input hours: q
Exit.

ex09:
编写一个程序,只接受正整数输入,然后显示所有小于或等于该数的素数。

#include <stdio.h>
#include <stdbool.h>

int main(void){
    unsigned long in;
    bool is_primer = true;

    printf("Enter an integer: ");
    scanf("%lu", &in);
    printf("Primers no larger than %lu:\n", in);
    for (int i = 3, j = 2; i <= in; ++i){
        for (j = 2, is_primer = true; j*j <= i; ++j){
            if (0 == (i % j)){
                is_primer = false;
                break;
            }
        }
        if (is_primer){
            printf("% 6d", i);
        }
    }
    printf("\n");

    return 0;
}

output:

Enter an integer: 50
Primers no larger than 50:
     3     5     7    11    13    17    19    23    29    31    37    41    43    47

ex10:
1988年的美国联邦税收计划是近代最简单的税收方案。它分为4个类别,每个类别有两个等级。
下面是该税收计划的摘要(美元数为应征税的收入):

类别 税金
单身 17850美元按15%计,超出部分按28%计
户主 23900美元按15%计,超出部分按28%计
已婚,共有 29750美元按15%计,超出部分按28%计
已婚,离异 14875美元按15%计,超出部分按28%计

例如,一位工资为20000美元的单身纳税人,应缴纳税费0.15×17850+0.28×(20000−17850)美元。编写一个程序,让用户指定缴纳税金的种类和应纳税收入,然后计算税金。程序应通过循环让用户可以多次
输入。

#include <stdio.h>
#define TAX_RATE0   0.15
#define TAX_RATE1   0.28

int main(void){
    double salary;
    double basic_salary;
    double tax;
    double real_salary;
    int select;

    printf("Select category: \n");
    printf("1)  单身       2) 户主\n"
            "3) 已婚,共有  4) 已婚,离异\n"
            "5) 退出\n");
    if (0 == scanf("%d", &select) || select < 0 || select > 5){
        printf("select:%d.\n", select);
        printf("Invalid input, exit.\n");
        return 0;
    }
    switch (select){
        case 1:
            basic_salary = 17850.;
            break;
        case 2:
            basic_salary = 23900.;
            break;
        case 3:
            basic_salary = 29750.;
            break;
        case 4:
            basic_salary = 14875.;
            break;
        default:
            printf("quit.\n");
            return 0;
    }
    printf("You chose %d.\n", select);

    printf("Enter your salary: ");
    while (0 != scanf("%lf", &salary)){
        tax = salary * TAX_RATE0;
        if (salary > basic_salary){
            tax += (TAX_RATE1 - TAX_RATE0) * (salary - basic_salary);
        }
        real_salary = salary - tax;
        printf("salary: %.2lf; tax: %.2lf; real_salary: %.2lf\n",
                salary, tax, real_salary);
        printf("Continue input hours: ");
    }

    return 0;
}

output:

Select category:
1)  单身       2) 户主
3) 已婚,共有  4) 已婚,离异
5) 退出
1
You chose 1.
Enter your salary: 20000
salary: 20000.00; tax: 3279.50; real_salary: 16720.50
Continue input hours: q

ex11:
ABC 邮购杂货店出售的洋蓟售价为 2.05 美元/磅,甜菜售价为 1.15美元/磅,胡萝卜售价为1.09美元/磅。
在添加运费之前,100美元的订单有5%的打折优惠。少于或等于5磅的订单收取6.5美元的运费和包装费,5磅~20磅的订单收取14美元的运费和包装费,超过20磅的订单在14美元的基础上每续重1磅增加0.5美元。

编写一个程序,在循环中用switch语句实现用户输入不同的字母时有不同的响应,即输入a的响应是让用户输入洋蓟的磅数,b是甜菜的磅数,c是胡萝卜的磅数,q是退出订购。
程序要记录累计的重量。即,如果用户输入 4 磅的甜菜,然后输入 5磅的甜菜,程序应报告9磅的甜菜。然后,该程序要计算货物总价、折扣(如果有的话)、运费和包装费。
随后,程序应显示所有的购买信息:物品售价、订购的重量(单位:磅)、订购的蔬菜费用、订单的总费用、折扣(如果有的话)、运费和包装费,以及所有的费用总额。

#include <stdio.h>

int main(void){
    int size = 3;
    char *category[] = {"洋蓟", "甜菜", "胡萝卜"};
    double price[] = {2.05, 1.15, 1.09};
    double weight[size];
    char in_category;
    double in_weight;
    int i;

    while (1){
        printf("Input category:\n");
        for (i = 0; i < size; ++i){
            if (0 != i%2){
                printf("         ");
            }
            printf("%c)  %s", 'a'+i, category[i]);
            if (0 == (i+1)%2){
                printf("\n");
            }
        }
        if (0 != i%2){
            printf("\n");
        }
        printf("q)  退出\n");
        while ('\n' == (in_category = getchar())){
        }
        if ('a' > in_category || ('a'+size-1 < in_category && 'q' != in_category)){
            printf("Invalid input: %c, reinput.\n", in_category);
            continue;
        }
        if ('q' == in_category){
            printf("Exit.\n");
            return 0;
        }

        printf("Input weight for %s: ", category[in_category-'a']);
        if (0 == scanf("%lf", &in_weight) || 0 > in_weight){
            printf("Invalid input, reinput.\n");
            continue;
        }
        weight[in_category-'a'] += in_weight;

        for (int i = 0; i < size; ++i){
            printf("% 10s: % 5.3lf", category[i], weight[i]);
            if (0 == i%2){
                printf("\n");
            }
        }
        printf("\n");
    }

    return 0;
}

output:

Input category:
a)  洋蓟         b)  甜菜
c)  胡萝卜
q)  退出
a
Input weight for 洋蓟: 5
    洋蓟:  5.000
    甜菜:  0.000 胡萝卜:  0.000

Input category:
a)  洋蓟         b)  甜菜
c)  胡萝卜
q)  退出
b
Input weight for 甜菜: 2
    洋蓟:  5.000
    甜菜:  2.000 胡萝卜:  0.000

Input category:
a)  洋蓟         b)  甜菜
c)  胡萝卜
q)  退出
q
Exit.
posted @ 2020-05-27 22:56  keep-minding  阅读(166)  评论(0)    收藏  举报