关于The C Programming Language

时间:2022-11-23 15:04:44
最近找了The C Programming Language的课后题答案,就是网上很多的那个CHM格式的英文版文档,觉得写的可以。但今天,竟然发现了这本书课后题答案的中文版本   http://www.doc88.com/p-46819468340.html   两者出入还比较大,我该信那个?

9 个解决方案

#1


这个还是运行一下 看看结果就知道了 答案都有可能是错的  以运行结果为主   不过我还是倾向于英文版

#2


我觉得应该是英文版本,因为它是英语书啊
不过你也可以找个有出入的放到这里来让大家看看,看看到底是哪个对

#3


也可能是不同版本的吧

#4


以你为准

在书中的例子里,中文版更改了几个明显的错误

#5


自己做下,然后看看哪个的答案和你的一样

#6


引用 2 楼 lvlufeng 的回复:
我觉得应该是英文版本,因为它是英语书啊
不过你也可以找个有出入的放到这里来让大家看看,看看到底是哪个对



这个是英文版本:
Answer to Exercise 1-18, page 31
Write a program to remove all trailing blanks and tabs from each line of input, and to delete entirely blank lines. 

 
/* K&R2 1-18 p31: Write a program to remove trailing blanks and tabs
   from each line of input, and to delete entirely blank lines.
 
   The program specification is ambiguous: does "entirely blank lines"
   mean lines that contain no characters other than newline, or does
   it include lines composed of blanks and tabs followed by newline?
   The latter interpretation is taken here.
 
   This implementation does not use any features not introduced in the
   first chapter of K&R2.  As a result, it can't use pointers to
   dynamically allocate a buffer to store blanks that it has seen, so
   it must limit the number of blanks that are allowed to occur
   consecutively.  (This is the value of MAXQUEUE, minus one.)
 
   It is intended that this implementation "degrades gracefully."
   Even though a particular input might have 1000 or more blanks or
   tabs in a row, causing a problem for a single pass, multiple passes
   through the file will correct the problem.  The program signals the
   need for such an additional pass by returning a failure code to the
   operating system.  (EXIT_FAILURE isn't mentioned in the first
   chapter of K&R, but I'm making an exception here.) */
 
#include <stdio.h>
#include <stdlib.h>
 
#define MAXQUEUE 1001
 
int advance(int pointer)
{
  if (pointer < MAXQUEUE - 1)
    return pointer + 1;
  else
    return 0;
}
 
int main(void)
{
  char blank[MAXQUEUE];
  int head, tail;
  int nonspace;
  int retval;
  int c;
 
  retval = nonspace = head = tail = 0;
  while ((c = getchar()) != EOF) {
    if (c == '\n') {
      head = tail = 0;
      if (nonspace)
        putchar('\n');
      nonspace = 0;
    }
    else if (c == ' ' || c == '\t') {
      if (advance(head) == tail) {
        putchar(blank[tail]);
        tail = advance(tail);
        nonspace = 1;
        retval = EXIT_FAILURE;
      }
 
      blank[head] = c;
      head = advance(head);
    }
    else {
      while (head != tail) {
        putchar(blank[tail]);
        tail = advance(tail);
      }
      putchar(c);
      nonspace = 1;
    }
  }
 
  return retval;
}
 



Chris Sidi writes: 

 
Ben,
 
I thought your solution to 1-18 was really neat (it didn't occur to me
when I was doing the exercise), the way it degrades gracefully and
multiple passes can get rid of huge blocks of whitespace.
 
However, if there is a huge block of non-trailing whitespace (eg "A",2000
spaces, "B\n") your program returns an error when there's not a need for
it.  And if someone were to use your program till it passes it will loop
infinitely:
 
  $ perl -e 'print "A"," "x2000,"B\n";' > in
  $ until ./a.out < in > out; do echo failed, running another pass; cp out
     in; done
  failed, running another pass
  failed, running another pass
  failed, running another pass
  [snip]
 
Below I have added a variable spaceJustPrinted to your program and check
to see if the spaces printed early are trailing.  I hope you like the
minor improvement.  (Though I can understand if you don't give a [1] :))
[1] expletive deleted - RJH. 

 
/* K&R2 1-18 p31: Write a program to remove trailing blanks and tabs
   from each line of input, and to delete entirely blank lines.
 
   The program specification is ambiguous: does "entirely blank lines"
   mean lines that contain no characters other than newline, or does
   it include lines composed of blanks and tabs followed by newline?
   The latter interpretation is taken here.
 
   This implementation does not use any features not introduced in the
   first chapter of K&R2.  As a result, it can't use pointers to
   dynamically allocate a buffer to store blanks that it has seen, so
   it must limit the number of blanks that are allowed to occur
   consecutively.  (This is the value of MAXQUEUE, minus one.)
 
   It is intended that this implementation "degrades gracefully."
   Even though a particular input might have 1000 or more trailing
   blanks or tabs in a row, causing a problem for a single pass,
   multiple passes through the file will correct the problem.  The
   program signals the need for such an additional pass by returning a
   failure code to the operating system.  (EXIT_FAILURE isn't mentioned
   in the first chapter of K&R, but I'm making an exception here.) */
 
#include <stdio.h>
#include <stdlib.h>
 
#define MAXQUEUE 1001
 
int advance(int pointer)
{
  if (pointer < MAXQUEUE - 1)
    return pointer + 1;
  else
    return 0;
}
 
int main(void)
{
  char blank[MAXQUEUE];
  int head, tail;
  int nonspace;
  int retval;
  int c;
  int spaceJustPrinted; /*boolean: was the last character printed whitespace?*/
 
  retval = spaceJustPrinted = nonspace = head = tail = 0;
 
  while ((c = getchar()) != EOF) {
    if (c == '\n') {
      head = tail = 0;
      if (spaceJustPrinted == 1) /*if some trailing whitespace was printed...*/
        retval = EXIT_FAILURE;
 
      if (nonspace) {
        putchar('\n');
        spaceJustPrinted = 0; /* this instruction isn't really necessary since
                              spaceJustPrinted is only used to determine the
                              return value, but we'll keep this boolean
                              truthful */
        nonspace = 0;  /* moved inside conditional just to save a needless
                       assignment */
      }
    }
    else if (c == ' ' || c == '\t') {
      if (advance(head) == tail) {
        putchar(blank[tail]); /* these whitespace chars being printed early
                              are only a problem if they are trailing,
                              which we'll check when we hit a \n or EOF */
        spaceJustPrinted = 1;
        tail = advance(tail);
        nonspace = 1;
      }
 
      blank[head] = c;
      head = advance(head);
    }
    else {
      while (head != tail) {
        putchar(blank[tail]);
        tail = advance(tail);
      }
      putchar(c);
      spaceJustPrinted = 0;
      nonspace = 1;
    }
  }
 
  /* if the last line wasn't ended with a newline before the EOF,
  we'll need to figure out if trailing space was printed here */
  if (spaceJustPrinted == 1) /*if some trailing whitespace was printed...*/ 
    retval = EXIT_FAILURE;
 
  return retval;



这个是中文版本,确实是正规出版的,在道客巴巴上有文档,上面写着机械工业出版社,只不过是什么“第二版·新版”,新版和原来差别这么大?下面是代码,原书是PDF影印的,这是我自己打的。上面还说getline和1.16中的同名函数一样,就粘来了:
#include<stdio.h>

#define MAXLINE 1000

int getline(char line[], int maxline);
int remove(char s[]);

main()
{
char line[MAXLINE];
while(getline(line, MAXLINE) > 0)
if(remove(line) > 0)
printf("%s",line);
return 0;
}

int remove(char s[])
{
int i;
while(s[i] != '\n')
++i;
--i;
while(i >= 0 && (s[i] == ' ' && s[i] == '\t'))
--i;
if(i >= 0)
{
++i;
s[i] = '\n';
++i;
s[i] = '\0';

}
return i;
}

int getline(char s[], int lim)
{
  int c, i, j;
  j = 0;
  for(i = 0; (c = getchar())!=EOF && c != '\n'; ++i)
  {
    if(i < lim - 2)
    {
      s[j++] = c;
    }
  }
  if(c == '\n')
  {
    if(i <= lim - 1)
    {
      s[j++] = c;
    }
    ++i;
  }
  s[j] = '\0';
  return i;
}

可惜的是运行失败了。高手们看看吧。我的理解是中文版的思路简单,而且是正规出版。而英文版的会给出好几个解答,而且能运行成功。

#7


好像英文版是爱好者写的,比如Ben Pfaff,Lew Pitcher, Rick Dearman几个英文名字常出现。他们写的是好,但不太好理解……有的没有注释,得靠标识符名字猜……

#8


相信电脑。

#9


不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。

#1


这个还是运行一下 看看结果就知道了 答案都有可能是错的  以运行结果为主   不过我还是倾向于英文版

#2


我觉得应该是英文版本,因为它是英语书啊
不过你也可以找个有出入的放到这里来让大家看看,看看到底是哪个对

#3


也可能是不同版本的吧

#4


以你为准

在书中的例子里,中文版更改了几个明显的错误

#5


自己做下,然后看看哪个的答案和你的一样

#6


引用 2 楼 lvlufeng 的回复:
我觉得应该是英文版本,因为它是英语书啊
不过你也可以找个有出入的放到这里来让大家看看,看看到底是哪个对



这个是英文版本:
Answer to Exercise 1-18, page 31
Write a program to remove all trailing blanks and tabs from each line of input, and to delete entirely blank lines. 

 
/* K&R2 1-18 p31: Write a program to remove trailing blanks and tabs
   from each line of input, and to delete entirely blank lines.
 
   The program specification is ambiguous: does "entirely blank lines"
   mean lines that contain no characters other than newline, or does
   it include lines composed of blanks and tabs followed by newline?
   The latter interpretation is taken here.
 
   This implementation does not use any features not introduced in the
   first chapter of K&R2.  As a result, it can't use pointers to
   dynamically allocate a buffer to store blanks that it has seen, so
   it must limit the number of blanks that are allowed to occur
   consecutively.  (This is the value of MAXQUEUE, minus one.)
 
   It is intended that this implementation "degrades gracefully."
   Even though a particular input might have 1000 or more blanks or
   tabs in a row, causing a problem for a single pass, multiple passes
   through the file will correct the problem.  The program signals the
   need for such an additional pass by returning a failure code to the
   operating system.  (EXIT_FAILURE isn't mentioned in the first
   chapter of K&R, but I'm making an exception here.) */
 
#include <stdio.h>
#include <stdlib.h>
 
#define MAXQUEUE 1001
 
int advance(int pointer)
{
  if (pointer < MAXQUEUE - 1)
    return pointer + 1;
  else
    return 0;
}
 
int main(void)
{
  char blank[MAXQUEUE];
  int head, tail;
  int nonspace;
  int retval;
  int c;
 
  retval = nonspace = head = tail = 0;
  while ((c = getchar()) != EOF) {
    if (c == '\n') {
      head = tail = 0;
      if (nonspace)
        putchar('\n');
      nonspace = 0;
    }
    else if (c == ' ' || c == '\t') {
      if (advance(head) == tail) {
        putchar(blank[tail]);
        tail = advance(tail);
        nonspace = 1;
        retval = EXIT_FAILURE;
      }
 
      blank[head] = c;
      head = advance(head);
    }
    else {
      while (head != tail) {
        putchar(blank[tail]);
        tail = advance(tail);
      }
      putchar(c);
      nonspace = 1;
    }
  }
 
  return retval;
}
 



Chris Sidi writes: 

 
Ben,
 
I thought your solution to 1-18 was really neat (it didn't occur to me
when I was doing the exercise), the way it degrades gracefully and
multiple passes can get rid of huge blocks of whitespace.
 
However, if there is a huge block of non-trailing whitespace (eg "A",2000
spaces, "B\n") your program returns an error when there's not a need for
it.  And if someone were to use your program till it passes it will loop
infinitely:
 
  $ perl -e 'print "A"," "x2000,"B\n";' > in
  $ until ./a.out < in > out; do echo failed, running another pass; cp out
     in; done
  failed, running another pass
  failed, running another pass
  failed, running another pass
  [snip]
 
Below I have added a variable spaceJustPrinted to your program and check
to see if the spaces printed early are trailing.  I hope you like the
minor improvement.  (Though I can understand if you don't give a [1] :))
[1] expletive deleted - RJH. 

 
/* K&R2 1-18 p31: Write a program to remove trailing blanks and tabs
   from each line of input, and to delete entirely blank lines.
 
   The program specification is ambiguous: does "entirely blank lines"
   mean lines that contain no characters other than newline, or does
   it include lines composed of blanks and tabs followed by newline?
   The latter interpretation is taken here.
 
   This implementation does not use any features not introduced in the
   first chapter of K&R2.  As a result, it can't use pointers to
   dynamically allocate a buffer to store blanks that it has seen, so
   it must limit the number of blanks that are allowed to occur
   consecutively.  (This is the value of MAXQUEUE, minus one.)
 
   It is intended that this implementation "degrades gracefully."
   Even though a particular input might have 1000 or more trailing
   blanks or tabs in a row, causing a problem for a single pass,
   multiple passes through the file will correct the problem.  The
   program signals the need for such an additional pass by returning a
   failure code to the operating system.  (EXIT_FAILURE isn't mentioned
   in the first chapter of K&R, but I'm making an exception here.) */
 
#include <stdio.h>
#include <stdlib.h>
 
#define MAXQUEUE 1001
 
int advance(int pointer)
{
  if (pointer < MAXQUEUE - 1)
    return pointer + 1;
  else
    return 0;
}
 
int main(void)
{
  char blank[MAXQUEUE];
  int head, tail;
  int nonspace;
  int retval;
  int c;
  int spaceJustPrinted; /*boolean: was the last character printed whitespace?*/
 
  retval = spaceJustPrinted = nonspace = head = tail = 0;
 
  while ((c = getchar()) != EOF) {
    if (c == '\n') {
      head = tail = 0;
      if (spaceJustPrinted == 1) /*if some trailing whitespace was printed...*/
        retval = EXIT_FAILURE;
 
      if (nonspace) {
        putchar('\n');
        spaceJustPrinted = 0; /* this instruction isn't really necessary since
                              spaceJustPrinted is only used to determine the
                              return value, but we'll keep this boolean
                              truthful */
        nonspace = 0;  /* moved inside conditional just to save a needless
                       assignment */
      }
    }
    else if (c == ' ' || c == '\t') {
      if (advance(head) == tail) {
        putchar(blank[tail]); /* these whitespace chars being printed early
                              are only a problem if they are trailing,
                              which we'll check when we hit a \n or EOF */
        spaceJustPrinted = 1;
        tail = advance(tail);
        nonspace = 1;
      }
 
      blank[head] = c;
      head = advance(head);
    }
    else {
      while (head != tail) {
        putchar(blank[tail]);
        tail = advance(tail);
      }
      putchar(c);
      spaceJustPrinted = 0;
      nonspace = 1;
    }
  }
 
  /* if the last line wasn't ended with a newline before the EOF,
  we'll need to figure out if trailing space was printed here */
  if (spaceJustPrinted == 1) /*if some trailing whitespace was printed...*/ 
    retval = EXIT_FAILURE;
 
  return retval;



这个是中文版本,确实是正规出版的,在道客巴巴上有文档,上面写着机械工业出版社,只不过是什么“第二版·新版”,新版和原来差别这么大?下面是代码,原书是PDF影印的,这是我自己打的。上面还说getline和1.16中的同名函数一样,就粘来了:
#include<stdio.h>

#define MAXLINE 1000

int getline(char line[], int maxline);
int remove(char s[]);

main()
{
char line[MAXLINE];
while(getline(line, MAXLINE) > 0)
if(remove(line) > 0)
printf("%s",line);
return 0;
}

int remove(char s[])
{
int i;
while(s[i] != '\n')
++i;
--i;
while(i >= 0 && (s[i] == ' ' && s[i] == '\t'))
--i;
if(i >= 0)
{
++i;
s[i] = '\n';
++i;
s[i] = '\0';

}
return i;
}

int getline(char s[], int lim)
{
  int c, i, j;
  j = 0;
  for(i = 0; (c = getchar())!=EOF && c != '\n'; ++i)
  {
    if(i < lim - 2)
    {
      s[j++] = c;
    }
  }
  if(c == '\n')
  {
    if(i <= lim - 1)
    {
      s[j++] = c;
    }
    ++i;
  }
  s[j] = '\0';
  return i;
}

可惜的是运行失败了。高手们看看吧。我的理解是中文版的思路简单,而且是正规出版。而英文版的会给出好几个解答,而且能运行成功。

#7


好像英文版是爱好者写的,比如Ben Pfaff,Lew Pitcher, Rick Dearman几个英文名字常出现。他们写的是好,但不太好理解……有的没有注释,得靠标识符名字猜……

#8


相信电脑。

#9


不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。