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,如需转载请自行联系原作者

相关文章
|
自然语言处理 异构计算
ICLR 2024 Poster:精确且高效的大语言模型低比特量化方法 QLLM
【2月更文挑战第24天】ICLR 2024 Poster:精确且高效的大语言模型低比特量化方法 QLLM
478 3
ICLR 2024 Poster:精确且高效的大语言模型低比特量化方法 QLLM
|
Java 前端开发
如何生成pem密钥
本帖是介绍使用支付宝提供的一键生成密钥工具和OpenSSL工具生成pem格式密钥,仅供参考!! 可参看开放平台文档链接实现:[url]https://docs.open.alipay.com/291/106097[/url] 1.直接使用支付宝提供的一键生成工具生成; 2.使用OpenSSL工具生成。
5335 0
|
PyTorch TensorFlow 算法框架/工具
Jetson环境安装(一):Ubuntu18.04安装pytorch、opencv、onnx、tensorflow、setuptools、pycuda....
本文提供了在Ubuntu 18.04操作系统的NVIDIA Jetson平台上安装深度学习和计算机视觉相关库的详细步骤,包括PyTorch、OpenCV、ONNX、TensorFlow等。
1124 1
Jetson环境安装(一):Ubuntu18.04安装pytorch、opencv、onnx、tensorflow、setuptools、pycuda....
|
运维 监控 NoSQL
【Redis】哨兵(Sentinel)原理与实战全解~炒鸡简单啊
Redis 的哨兵模式(Sentinel)是一种用于实现高可用性的机制。它通过监控主节点和从节点,并在主节点故障时自动进行切换,确保集群持续提供服务。哨兵模式包括主节点、从节点和哨兵实例,具备监控、通知、自动故障转移等功能,能显著提高系统的稳定性和可靠性。本文详细介绍了哨兵模式的组成、功能、工作机制以及其优势和局限性,并提供了单实例的安装和配置步骤,包括系统优化、安装、配置、启停管理和性能监控等。此外,还介绍了如何配置主从复制和哨兵,确保在故障时能够自动切换并恢复服务。
|
机器学习/深度学习 人工智能 自然语言处理
人工智能的发展领域
【5月更文挑战第17天】人工智能的发展领域
711 3
|
UED
【亮剑】无线AP在中小型和大型网络环境中的两种组网方式——分布式和集中式。
【4月更文挑战第30天】本文探讨了无线AP在中小型和大型网络环境中的两种组网方式——分布式和集中式。分布式组网适合中小型网络,成本低、部署简单,但管理复杂性和漫游体验有限。案例显示,分布式组网能满足小公司基本需求。而在大型网络中,集中式组网提供统一管理、无缝漫游和高稳定性,但初期投资大、维护复杂。大型购物中心采用集中式组网,实现了全面覆盖和客户体验提升。企业应根据需求和预算选择合适组网策略。
546 1
|
JSON 小程序 安全
【经验分享】如何实现小程序日历范围选择功能
【经验分享】如何实现小程序日历范围选择功能
820 13
|
敏捷开发 开发框架 架构师
敏捷开发发展和优缺点 1
敏捷开发发展和优缺点
561 0
|
存储 小程序
小程序实现购物车功能
购物车功能是电商小程序中比较常见的功能之一,实现起来也比较简单。通过本文的介绍,我们可以学习到如何将用户所选的商品信息保存在本地,如何展示商品信息,如何计算商品总价和总数,以及如何提供用户对购物车中商品的操作。在实际开发中,还可以根据具体需求进行定制和优化,例如添加优惠券、满减活动等功能,提升用户购物体验。
606 0