20200910-3 命令行和控制台编程

此作业的要求参见: 作业要求 20200910-3 命令行和控制台编程

1.熟悉 命令行 和 控制台/标准输入和标准输出

(1)假设在当前目录下存在应用程序 a.exe 和 文件文件 b.txt,请以数据流图并辅助以文字说明下述控制台命令的作用是什么。(5分)

a.exe < b.txt > c.txt

A: 该指令运行了程序a.exe,并将b.txt的文件内容重定向为a.exe的输入,之后,又将a.exe的输出重定向到文件c.txt(新建c.txt或覆盖c.txt原有内容)。

数据流图如下:

数据流图

@startuml digraph DFG { rankdir=LR store1 [label="b.txt" shape="box"] proc1 [label="a.exe" shape=circle] store2 [label="c.txt" shape="box"] store1 -> proc1[label="input"] proc1 -> store2[label="output"] } @enduml

(2)请用C语言开发应用程序d.exe,从控制台指令读入命令行参数,并在控制台分别打印出a、b、c的值。运行效果形如下面的示例(6分)

d.exe a=1 b=2 c=3

1

2

3
d.exe a=11 b=22 c=33

11

22

33

A: 该题的要点在于使用main函数的参数获取到运行程序时提供的输入,代码如下:

#include <stdio.h>
#include <string.h>

// Command Line Arguments of C Language
// argc: nuber of arguments;
// argv: string array of arguments.
int main(int argc, char *argv[]){
    // cat all string in string array argv as one string.
    char *argStr = (char *)calloc(1, sizeof(char));
    for(int ii = 1; ii < argc; ii++){
        argStr = strcat(argStr, argv[ii]);
        argStr = strcat(argStr, " ");
    }

    // get number in argStr which converted from arguments input.
    int a, b, c;
    sscanf(argStr, "a=%d b=%d c=%d", &a, &b, &c);
    printf("\n%d\n\n%d\n\n%d", a, b, c);
    return 0;
}

运行效果如下:

2.熟悉 测试用例

(1)请在网站 [https://pintia.cn/]注册账号。(0分)

A: 已注册。

(2)在题目集 PAT (Basic Level) Practice (中文) 中任选3道题目完成。截图如下,要求包括1.红色对号、2.标号、3.用户名(此例中为 Young)。(30分)

注意,需要读完本作业全部题目才能开始做题,有对时间记录和代码解读的要求。

A:

截图如下:

(3)代码解读 (20分)

Q: 发表博客,介绍上述3个题目代码中重点/难点,展示重要代码片断,给出执行效果截图,展示你感觉得意、突破、困难的地方。

代码片断要求1 凡不缩进的,此题目拒绝接收。不知道什么是“缩进”的同学,请自行补课,不接受以“不知道”作为理由。

代码片断要求2 要求使用cnblogs代码控件,参见往届同学黄兴、宫成荣的作业。凡粘贴IDE中的代码截图,或者贴文字而没有关键字高亮或彩色的,0分。

[http://www.cnblogs.com/huangxman/p/5871201.html]

[http://www.cnblogs.com/gongcr/p/5873493.html]

A:

I. 1001 害死人不偿命的(3n+1)猜想 (15point(s))

题目详细描述见链接

本题难度较低,使用循环对数据反复求解即可,需要注意的是循环条件是 n!= 1, 而不是 n != 0。代码如下:

#include <stdio.h>

int main(){
    // get int number which named n from std input.
    int n;
    scanf("%d", &n);

    // counter
    int count = 0;

    // test count in loop until n is less or equal 1
    while(n != 1){
        if( n % 2 == 0){ // n is enev, n = n / 2
            n = n / 2;
        }else{ // n is odd, n = (3 * n + 1) / 2
            n = (3 * n + 1) / 2;
        }
        // count ++
        count++;
    }

    // output count
    printf("%d", count);
}
II. 1002 写出这个数 (20point(s))

题目详细要求见链接

本题有如下几个要点需要关注:

  1. 输入的数字可能会超出int类型的范围,故最好使用字符串来保存输入的数字;

  2. 在C语言中,数字字符转换为对应的数字只需要减去字符‘0’,即int num = num_ch - '0'; // num_ch 是一个数字字符;

  3. 对于计算结果的数字输出,需要按从左到右的顺序,这需要一个数组来保存输出结果字符串的指针,以便于结果输出。

实现代码如下:

#include <stdio.h>

int main(){
    // get input number as a string(char array)
    char n[101];
    scanf("%s", &n);
    
    // calc sum of each digit
    int sum = 0, n_i = 0;
    while(n[n_i] != '\0'){
        // char of number to int number
        // ch - '0'
        sum = sum + (n[n_i++] - '0'); 
    }

    // alphabets string table
    char alphabets[][5] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};

    // fix out strings
    char *reout[10];
    int reout_i = 0;

    while(sum > 0){
        reout[reout_i++] = alphabets[sum % 10];
        sum = sum / 10;
    }
    // print
    while(reout_i > -1){
        printf("%s", reout[--reout_i]);
        if(reout_i > 0){
            printf(" ");
        }
    }
}
III. 1003 我要通过! (20point(s))

题目详情见链接

题目中提到字符串符合要求的条件是,

字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。

通过分析,可以将判定正确的条件分解如下:

  1. 只包括字符APT, 不得出现其他字符;

  2. 字符APT都至少有一个;

  3. 字符T必须出现在字符A之后;

  4. 对于字符A的数量有要求,要求如下: 将字符A在字符P之前的数量记为C1, 在PT之间的数量记为C2,在T之后的数量记为C3,存在关系C1 * C2 = C3

实现代码如下:

#include <stdio.h>

int judge(char *str)
{
    int A_befor_P = 0, A_in_PT = 0, A_after_T = 0, P = 0, T = 0, flag = 1;

    while (*str != '\0')
    {
        if (*str == 'A')
        {
            if (P == 0)
            {
                A_befor_P++;
            }
            else if (P > 0 && T == 0)
            {
                A_in_PT++;
            }
            else if (P > 0 && T > 0)
            {
                A_after_T++;
            }
        }
        else if (*str == 'P')
        {
            if (P == 0)
            {
                // first 'P'
                P++;
            }
            else
            {
                // break
                flag = 0;
                break;
            }
        }
        else if (*str == 'T')
        {
            if (T == 0 && P == 1)
            {
                // first 'T' after 'P'
                T++;
            }
            else
            {
                // break
                flag = 0;
                break;
            }
        }
        else
        {
            // have char not 'A', 'P' or 'T'
            // faild and stop loop
            flag = 0;
            break;
        }

        str++;
    }

    if (!(flag != 0 && P > 0 && T > 0 && A_in_PT > 0 && A_befor_P * A_in_PT == A_after_T))
        flag = 0;

    return flag;
}

int main()
{
    // get lines number
    int n;
    scanf("%d", &n);

    char str[101];
    for (int ii = 0; ii < n; ii++)
    {
        // get line
        scanf("%s", str);

        // judge this string
        if (1 == judge(str))
        {
            printf("YES");
        }
        else
        {
            printf("NO");
        }

        // just print newline (\n) before last one
        if (ii < n - 1)
        {
            printf("\n");
        }
    }
}

(4)控制台应用 (15分)

要求在博客中给出测试数据。

参照上一题中“控制台”的知识,给出运行时从控制台读入测试数据和向控制台输出的截图。

A:

更多题目描述和代码实现等信息,请查看2.(3)

I. 1001 害死人不偿命的(3n+1)猜想 (15point(s))

输入如下:

3

输出如下:

5

运行截图如下(结尾的%字符是终端表示输出已经结束的标识符,并非程序本身的输出):

II. 1002 写出这个数 (20point(s))

输入如下:

1234567890987654321123456789

输出如下:

yi san wu

运行截图如下:

III. 1003 我要通过! (20point(s))

输入如下:

8
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA

输出如下:

YES
YES
YES
YES
NO
NO
NO
NO

运行截图如下:

由于是截图,无法区分输入输出。在图例中,除第一行数字的输入外,其他的内容都是两行一组,一组中,第一行为输入,第二行为输出。
该程序已经通过PTA OJ系统测试,属于正确处理。

图表过小、字迹不清、错别字、句子不通顺的,教师会因为读不懂而对此题扣分。

(5) PSP(8分)

在同一篇博客中,参照教材第35页表2-2和表2-3,为上述3个题目制作PSP阶段表格。

PSP阶段表格第1列分类,如功能1、功能2、测试功能1等。

A:

题目 预计花费时间 实际花费时间 花费时间差距 原因
1001 15min 14min -1min 题目较为简单,描述清晰,较快完成任务。
1002 15min 20min +5min 没有注意到题目描述中对数字的限制范围,导致使用int保存输入而需要重构。
1003 20min 40min +20min 题目难度较高,分析条件有一定难度。同时,编码时忽略了一个条件,导致一个测试用例一直没法通过,检查花费了较长时间。
要求1 估算你对每个功能 (或/和子功能)的预计花费时间,填入PSP阶段表格,时间颗粒度为分钟。

要求2 记录词频统计项目实际花费时间,填入PSP阶段表格,时间颗粒度要求分钟。

要求3 对比要求1和要求2中每项时间花费的差距,分析原因。

posted @ 2020-09-14 13:55  WenqiangXie  阅读(149)  评论(3编辑  收藏  举报