The C Programming Language 1-9

 

The C Programming Language 1-9 — Windows Live

我用了位置标识的方法,虽然有点臃肿,不过道理还是很明显的

#include <stdio.h>

#define WAIT 0   //an initial place
#define FIRST 1  //a place in the first blank
#define OTHER 2  //a place in the balnk that follows
#define WORD 3   //a place in a word
#define FIRST_OVER 4

main()
{
    long state,c;
    state = WAIT;
    c = getchar();
    while (c != EOF)
    {
    //make state into different value
        if ((state == WAIT) && (c == ‘ ‘)){
                state = FIRST;
                }
        if ((state == FIRST_OVER) && (c == ‘ ‘)){
                state = OTHER;
                }
        if ((state == OTHER) && (c != ‘ ‘)){
                state = WORD;
                }
        if ((state == WAIT) && (c != ‘ ‘)){
                state = WORD;
                }
     //process the character string by different value of state          
        if (state == FIRST){
                putchar(c);
                state = FIRST_OVER;
                }
        if (state == WORD){
                putchar(c);
                state = WAIT;
                }
        c = getchar();
    }
    system("pause");
}

1.5.2 character counting

Nothing is odd with the program here but if you don’t take care of two points here,you may get puzzled with the output display.

//1.5.2 character counting

#include <stdio.h>
main()
{
    long cn;
    cn = 0;
    while (getchar() != EOF){
        ++cn;
        }
    printf("%1d\n",cn);
    system("pause");
}

image 
I can’t get the result at first,for that time,I directly enter a string with an ENTER,but find nothing given,that is,it don’t seem to work properly but the code is properly written,what’s wrong?
Asking a friends,I get the result,there’s nothing wrong with the code,but something not properly with the output.Check with the DOS blank like this:
type in a string that you want to test,and then turn to a new line type in ctrl and z,at last you will get a properly displayed answer.

ctrl+Z在控制台中就是EOF,输入的字符串末尾没有EOF,所以while循环会无限执行下去,以致无法执行printf部分,所以在控制台中输入zrtl+Z,给定一个EOF使得输入的string有这个结束符,就能跳到下一个printf了

1.5.1 file copying

Get inputs from related service,like keyboard,and then copy what you get to the output,like screen.

/*1.5.1 file copying – original version*/

#include <stdio.h>
main()
{
    int c = 0;
    c = getchar();
    while (c != EOF)
    {
        putchar(c);
        c = getchar();
    }
}

There’s something interesting here,we’ve learned printf() before,if we use it here,what will happen?

/*1.5.1 file copying*/

#include <stdio.h>
main()
{
    int c = 0;
    c = getchar();
    while (c != EOF)
    {
        c = getchar();
        printf("%d\n",c);
    }
}

The output of this program display input characters’ ASCII code instead of its original value and this is something different from putchar().
But I still have a question about it.It works alright but I’m afraid at the first input,it will return something,as far as I’m concerned,not properly designed.
If I type in one character,’1’ or ‘a’ for example,it will eventually give me a ‘10’,which,in the ASCII code,stands for Null;
11

and if I type in a string,’abcdef’ for instance,it will feedback every character’s ASCII code properly but lacks the last one’s own ASCII code instead of 10,which stands for a Null character;
1

if I type in nothing but only give an ‘Enter’,it will feedback nothing at all.
 
All the phenomenon above only exist at the first typing in,while at the next that follow,it will feedback properly.
As far as I am concerned,every character,no matter one character or a string,is terminated with a ‘’ whose ASCII code  is 10,but why the program fail to give input’s own ASCII code instead of only showing a ‘’\o’ ‘s?

用printf()替代putchar()之后,运行程序出现了一个比较有趣的问题。
第一次出入的字符总会得到错误的结果:如果输入单个字符,则只会返回10,而10在ASCII码中代表的是空位符;如果输入一个字符串,则字符串中最后一位字符的ASCII码无法得到,取而代之的还是一个10;如果什么也不输入,而只回车的话,就会什么也不得到。
然而上面这些现象在第二次输入时就不再出现了,所有的输入都得到想要的结果,当然,第二次输入回车还是会返回一个10.

现在我所掌握掌握的知识是,一个字符串,无论是单个字符还是一连串的字符,都是以结尾的,所以上面显示的10正是这个字符,可是为什么第一次输入的时候会出现错误呢?

The C Programming Language | Exercise 1-8

/*Exercise 1-8*/
#include <stdio.h>

main()
{
    int c,nb,nt,nn;
    c = 0;
    nb = 0;
    nt = 0;
    nn = 0;
    printf ("please enter a paragraph to test its blanks,tabs and newlines");
    while ((c = getchar()) != EOF)
        if (c == ‘ ‘)
                ++nb;
        if (c == ‘\t’)
                ++nt;
        if (c == ‘\n’)
                ++nn;
    printf ("OK,after computing,the pc will tell you there are"
            "%d blank(s) %d tab(s) and %d new line(s)",nb,nt,nn
            );
    system("pause");
}

———————-
我发现我很喜欢重新翻出这一条作业来做!不过,多做以后可以发现很多问题.

1.有关函数的声明
这里采用的方法绝对是最原始最浪费内存的,不过在第二章以后将采用新的方法
2.printf函数中显示的部分双引号内部的信息只能写一行,要是有多行则每行都应该使用一个引号括起来
3.最后一句话system(pause);用于防治程序运行后马上关闭,不过现在还不是很清楚为什么要这样做

The C Programming Language 1-9

练习1-9 编写一个将输入复制到输出的程序,并将其中连续的多个空格用一个空格代替。

这个问题其实考虑起来有个思维过程。先看一个例子
I have a blank I  have  two  I   have   three
这里理所当然要使用到getchar()函数来处理,所以要有字符流的思维,因此上面的字符串可以归为三种情况:(每次getchar()返回一个字符)
1,返回的是字母,则直接另输出的就是字符本身即可
2,返回的是空格,且该空格的前一个字符是字母,则另该空格为其本身即可
3,返回的是空格,但该空格的前一个字符也是空格(也就是体重所谓的“多个空格”),则将其替换为”
上面的三种情况可以由三个if语句来构成,但是这样写过于麻烦。不妨回头看一下三个情况,似乎可以合并成两个。的确,情况一和情况二所作的处理都是相同的,即另输出为输入,因此这里可以用一个if-else语句来简化。考虑到情况3较容易陈述,故将其放入if中,其余情况用else代替,可缩短整片语句。

#include <stdio.h>

main()
{
int n = 0;
int str[n] = getchar();

while (n = 0;str[n] != EOF;n++)
    if(str[n] == ‘ ‘ || str[n – 1] == ‘ ‘)
        str[n] = ”;
    else
        str[n] = str[n];
    putchar(str[n]);
}

——————————————-
但是这条程序还是有问题,编译器检测到数组的初始化有问题(
int str[n] = getchar();这部分有问题),可是我查阅了数组初始化的资料发现似乎没错啊~真不知道为什么了。先放着,以后想到再回头看看。
同时这条程序还有一个隐藏的危险,就是利用数组来存储getchar()返回的内容可能会放不下,而出现错误。这个我记得似乎有解决方法的~不过暂时想不出来了,想到了再回头重新弄弄尴尬


以下是姬失准的参考程序

The C Programming Language 1-9

其中方法一和我的思路相同,但似乎他用了stdlib.h中的lastc,这个啥玩意我不知道Confused 以后研究stdlib.h了再回头看看,似乎他那条很简洁的。
方法二的话实在是看不懂了。Sarcastic

关于“取模”运算的实验

一直以来都无法理解取模的具体操作。现在不妨先做个实验,究竟取模的结果是什么。代码如下:

#include <stdio.h>
main()
{
    printf("1 \37 3 = %d\n",1%3);
    printf("2 \37 3 = %d\n",2%3);
    printf("3 \37 3 = %d\n",3%3);
    printf("4 \37 3 = %d\n",4%3);
    printf("5 \37 3 = %d\n",5%3);
    printf("6 \37 3 = %d\n",6%3);
}

执行生成文件后形成如下内容:
1 % 3 = 1
2 % 3 = 2
3 % 3 = 0
4 % 3 = 1
5 % 3 = 2
6 % 3 = 0
先分析大于三的数与三进行取模运算。4%3上1余1,其余的5和6也是类似的计算,所以大于三的数与三进行取模运算比较好理解。接着再来看小于及等于三的数,先看三本身,取模上一余0,所以为0;接着看2,上0余下的就是2本身,同样1也是余下1本身。
所以可以总结出取模运算实质就是“除法后余下的零头”但是要注意“上0进行除法”的情况,即上述1和2与3进行取模运算。

——–
题外话,这个程序编译的时候出现了点小问题,在printf函数的双引号内想要打出百分号不能够直接键入%,因为这里的1%3在双引号中表示的是1这个数用三个字符的位置来显示。所以必须得换作用转义字符,查ASIIC表后发现百分号是第37个,所一用/37来表示百分号,前后记得要加上空格。

The C Programming Language Exercise 1-12

一万行代码的目标,从现在开始
今天从很久以前停止的地方开始。虽然已经把c给看完了,可是今天编的这行代码还是不得,问题的关键还是没掌握到,编的下面这行代码在连接过程中出现了死循环的情况,我不知道为什么。后来偷看了一下姬失准给出的参考答案,很佩服他,竟然用了宏OUT和IN的定义,这个正是这个练习题钱所教授的内容,我这里还没有用到,真是可惜。这个代码现在我还是没发现有什么错误,不过总会发现的。

#include
main()
{
int c = getchar();

if(c == ‘ ‘)
c = ‘\n’;
else
c = c;

printf{"%c",putchar(c)};
}