再读《The C Programming Language》 - 第一章 1.5 字符输入输出

1.5 字符输入/输出

第五节,是我最喜欢的章节!因为终于可以接触输入输出了,我可以敲打键盘,把我的想法打给电脑,电脑也可以打印出我一些消息给我看!多好啊,我和电脑终于有了一点点交流了,就像谈恋爱一样,终于牵了她的小手,弄的我小心肝扑扑跳个不停。这就是最基本的人机交互了。

第五小结分了4个小节,每节分别举了1个例子,以前总是囫囵吞枣的,借这个机会好好梳理下。
#include <stdio.h>

/* copy input to output; 1st version*/
int main()
{
    int c;
    c = getchar();
    while(c != EOF)
    {
        putchar(c);
        c = getchar();
    }
    getchar();    
}



该程序好小巧哈,这个程序也很基础,正如书上所言:“在以后你会发现其他复杂的程序也只是这些简单程序的扩充而已”
在这个程序里,我们认识了两个新的函数 getchar() , putchar(); 还有一个EOF,这个EOF(end of file) 就是我们上节所说的字符常量啦!它被定义多少呢?这个可以查看<stdio.h>文件,#define EOF (-1),那我们怎么从键盘输入这个-1呢?难道 先按“-”然后在按“1”,哇卡卡~想当然了,可以试下,这样做是不行的,这个是是这样规定的在Windos 操作系统是Ctrl+Z ;Linux系统下则是Ctrl + D;好了,去玩下这个程序先~~~就向小时候对着岩洞吼,“嘿!嘿!嘿!” 岩洞回应“诶!诶!诶!...”

输着输着是不是发现了有点什么不妥呢?是不是感觉有点怪怪的~~~这个怪怪的感觉本章结束的时候我们在来提...接着往下走...

Exercise发现英文版的书这个单词拼错了) 1-6. Verify that the expression getchar() != EOF is 0 or 1. 
#include <stdio.h>

/* Verify getchar() != EOF is 1 or 0*/
int main()
{
    while(1)
    {
        printf("getchar() != EOF is %d\n", getchar() != EOF);
    }
    getchar();    
}
运行下,是不是怪怪的,但似乎让其一个隐身人显身了。

Exercise 1-7. Write a program to print the value of EOF. 
#include <stdio.h>

/* Print EOF value */
int main()
{
    printf("EOF is %d\n", EOF);
    getchar();    
}

让我再看下一个例子
#include <stdio.h>  /* 头文件 */
#include <stdlib.h>

/* count characters in input; 2nd version */
int main()
{
    double nc;
    for(nc = 0; getchar() != EOF; ++nc)
        ;
    printf("%.0f\n", nc);

    system("PAUSE"); /* 系统暂停运行,可以方便看到显示结果 */
}

我运行玩玩输入“abcdef”回车 + ^z 

运行这个程序,我觉得这个程序似乎不怎么对,但以前也不敢怀疑大师呀~这个是不是就是前面提的怪怪的感觉呢?
想要消除这种感觉就要去GOOGLE去CSDN刨根问题 具体内容参考《getchar、scanf以及缓冲区的概念》这片文章也需可以给你解惑~

下个例子  计算行
#include <stdio.h>  /* 头文件 */
#include <stdlib.h>

/* count line in input; 1nd version */
int main()
{
    int c, nl;
    nl = 0; /* 初始化很重要 */
    while((c = getchar()) != EOF)
        if(c == '\n')
            ++nl;
    printf("%d\n", nl);

    system("PAUSE"); /* 系统暂停运行,可以方便看到显示结果 */
}
运行结果

这里首次引入了if语句,以后还会经常用到的;这里也提到ASCII字符集,这个是每个程序员都要去了解的,类似以前背的元素周期表~呵呵~类似~,好了,我做题了

Exercise 1-8. Write a program to count blanks, tabs, and newlines.
 Blanks = ' '  ,0x20; tabs = '\t' , 0x09, newlines = '\n', 0x0A
#include <stdio.h>  /* 头文件 */
#include <stdlib.h>

/* count newline, blanks and tabs */
int main()
{
    int c, nl,nb,nt;
    nl = 0; /* 初始化很重要 */
    nb = 0;
    nt = 0;
    while((c = getchar()) != EOF)
    {
        if( c == '\n')
            ++nl;
        if( c == ' ')
            ++nb;
        if( c == '\t')
            ++nt;

    }
    printf("nl = %d, nb = %d, nt = %d\n", nl, nb, nt);

    system("PAUSE"); /* 系统暂停运行,可以方便看到显示结果 */
}

Exercise 1-9. Write a program to copy its input to its output, replacing each string of one or more blanks by a single blank.
表示有点难度~
思路:如果遇到非空格字符依次打印,遇到第一个空格打印并记录打印状态(做个标记),如果接下来的还是空格则忽略,如果接下来的为非空格,则将状态清空。
#include <stdio.h>  /* 头文件 */
#include <stdlib.h>

#define MARKED          1
#define NO_MARKED       0

/* copy inputs and replacing banks by a single blank */
int main()
{
    int c;
    int bstate = NO_MARKED;
    while((c = getchar()) != EOF)
    {
        if(c == ' ')
        {
            if(bstate == NO_MARKED)
            {
                bstate = MARKED;
                putchar(c);
            }
        }
        else
        {
            bstate = NO_MARKED;
            putchar(c);
        }

    }

    system("PAUSE"); /* 系统暂停运行,可以方便看到显示结果 */
}
Exercise 1-10. Write a program to copy its input to its output, replacing each tab by \t, each backspace by \b, and each backslash by \\. This makes tabs and backspaces visible in an unambiguous way. 

#include <stdio.h>  /* 头文件 */
#include <stdlib.h>

#define TAB          '\t'
#define BLANK        ' '
#define BACKSLASH    '\\'

/* copy inputs and replacing banks by \b;tabs by \t; backslash by \\ */
int main()
{
    int c;
    while((c = getchar()) != EOF)
    {
        if( c == TAB)
        {
            putchar('\\'); // Replace by BACKSLASH
            putchar('t');
        }
        else if( c == BLANK )
        {
            putchar(BACKSLASH);
            putchar('b'); 
        }
        else if( c == BACKSLASH )
        {
            putchar(BACKSLASH);
            putchar(BACKSLASH);
        }
        else
        {
            putchar(c);
        }

    }

    system("PAUSE"); /* 系统暂停运行,可以方便看到显示结果 */
}

最后一个例子
#include <stdio.h>  /* 头文件 */
#include <stdlib.h>

#define IN          1
#define OUT         0

/* count lines, words and characters in input */
int main()
{
    int c;
    int nl, nw, nc, state;
    state = OUT;
    nl = nw = nc = 0;
    while((c = getchar()) != EOF)
    {
        ++nc;
        if( c == '\n' )
            ++nl;  
        if( c == ' ' || c == '\n' || c == '\t')
            state = OUT;
        else if( state == OUT )
        {
            state =  IN;
            ++nw;
        }
    }
    printf("nl = %d, nc = %d, nw = %d\n", nl, nc, nw);

    system("PAUSE"); /* 系统暂停运行,可以方便看到显示结果 */
}

也是经典的例子,多经典,引用文中的一段话“This is a bare-bones version of the UNIX program wc. ”
参考链接:A Source of the wc command 有兴趣的同学可以去瞅瞅(如果文中的连接你无法显示,那么就就应该去翻墙了)~

做习题了~~~

Exercise 1-11. How would you test the word count program? What kinds of input are most likely to uncover bugs if there are any? 

这题~这题~我真的不会,我的水平只知道在黑框里随便敲几个单词,然后对了,我就认为程序可以了,这个心态我自己这道是不可以的,做爬代码的,严谨是排第一位的!虽然没有标准答案,但我在网上找了个比较好的答案给大家参考。

It sounds like they are really trying to get the programmers to learn how to do a unit test. I would submit the following: 

  • 0. input file contains zero words 
  • 1. input file contains 1 enormous word without any newlines 
  • 2. input file contains all white space without newlines 
  • 3. input file contains 66000 newlines 
  • 4. input file contains word/{huge sequence of whitespace of different kinds}/word 
  • 5. input file contains 66000 single letter words, 66 to the line 
  • 6. input file contains 66000 words without any newlines 
  • 7. input file is /usr/dict contents (or equivalent) 
  • 8. input file is full collection of moby words 
  • 9. input file is binary (e.g. its own executable) 
  • 10. input file is /dev/nul (or equivalent) 

66000 is chosen to check for integral overflow on small integer machines. 

Exercise 1-12. Write a program that prints its input one word per line. 
想到做的那个空格移除的程序(Exercise 1-9),改改应该就可以用了吧!
#include <stdio.h>  /* 头文件 */
#include <stdlib.h>

#define MARKED          1
#define NO_MARKED       0

/* copy inputs and print a word in newline */
int main()
{
    int c;
    int bstate = NO_MARKED;
    while((c = getchar()) != EOF)
    {
        if(c == ' ' || c == '\t' || c == '\n') /* 判断条件 */
        {
            if(bstate == NO_MARKED)
            {
                bstate = MARKED;
                putchar('\n');  /* 输出回车 */
            }
        }
        else
        {
            bstate = NO_MARKED;
            putchar(c);
        }

    }

    system("PAUSE"); /* 系统暂停运行,可以方便看到显示结果 */
}

【本小节完】

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值