c程序设计语言_习题1-18_删除输入流中每一行末尾的空格和制表符,并删除完全是空格的行

简介:

 

Write a program to remove all trailing blanks and tabs from each line of input, and to delete entirely blank lines. 


其实做这道题目有两种思路:

  1.后向模式:利用getline()先将输入流中,每一行完全接收,然后从接收的line字符串中末尾,往前扫,直到发现第一个非空格和制表符字符;

  2.前向模式:每接收一个字符,都要进行输出、判断。

 

复制代码
/* 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,只能说明输入行中字符溢出了。
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;
}
复制代码

 

本文转自二郎三郎博客园博客,原文链接:http://www.cnblogs.com/haore147/p/3648256.html,如需转载请自行联系原作者

相关文章
|
2月前
|
移动开发 Unix C语言
日常知识点之c语言按行读配置文件,及行尾符CRLF导致的问题
日常知识点之c语言按行读配置文件,及行尾符CRLF导致的问题
57 0
|
2月前
|
存储 编译器 C语言
牛客网学习之倒置字符串(详解fgets函数,如何读取含有空格的字符串)
牛客网学习之倒置字符串(详解fgets函数,如何读取含有空格的字符串)
40 0
如何去掉字符串开头,结尾或者中间的空格及其他不想要的字符
去掉文本字符串开头,结尾或者中间不想要的字符,比如空白。
|
2月前
|
C语言 C++
每天一道C语言编程:(去掉:双斜杠注释,去掉空格)
每天一道C语言编程:(去掉:双斜杠注释,去掉空格)
10 0
|
2月前
|
Java
java读取txt文件,使用逗号,分号,空格,回车将文件内容分割成一个一个的词组,找出所有重复的词组
java读取txt文件,使用逗号,分号,空格,回车将文件内容分割成一个一个的词组,找出所有重复的词组
111 38
|
12月前
|
存储 C语言 C++
【C语言】如何读取带空格的字符串?
【C语言】如何读取带空格的字符串?
399 0
|
算法 安全
每日算法刷题Day7-比较字符串大小,去掉多余的空格,单词替换
⭐每日算法题解系列文章旨在精选重点与易错的算法题,总结常见的算法思路与可能出现的错误,与笔者另一系列文章有所区别,并不是以知识点的形式提升算法能力,而是以实战习题的形式理解算法,使用算法。
243 0
每日算法刷题Day7-比较字符串大小,去掉多余的空格,单词替换
去掉多余的空格---输入一个字符串,字符串中可能包含多个连续的空格,请将多余的空格去掉,只留下一个空格。输入格式
输入一个字符串,字符串中可能包含多个连续的空格,请将多余的空格去掉,只留下一个空格。 输入格式 共一行,包含一个字符串。 输出格式 输出去掉多余空格后的字符串,占一行。 数据范围 输入字符串的长度不超过 200200。 保证输入字符串的开头和结尾没有空格。
294 0
编写一个程序,将a.txt文件中的单词与b.txt文件中的单词交替合并到c.txt文件中,a.txt文件中的单词用回车符分隔,b.txt文件中用回车或空格进行分隔
编写一个程序,将a.txt文件中的单词与b.txt文件中的单词交替合并到c.txt文件中,a.txt文件中的单词用回车符分隔,b.txt文件中用回车或空格进行分隔
VB编程:去除文本框首尾空行-51
VB编程:去除文本框首尾空行-51
175 0