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 - )
return pointer + ;
else
return ;
} int main(void)
{
char blank[MAXQUEUE];
int head, tail;
int nonspace;
int retval;
int c; retval = nonspace = head = tail = ;
while ((c = getchar()) != EOF) {
if (c == '\n') {
head = tail = ;
if (nonspace)
putchar('\n');
nonspace = ;
}
else if (c == ' ' || c == '\t') {
//能执行这个if,只能说明输入行中字符溢出了。
if (advance(head) == tail) {
putchar(blank[tail]);
tail = advance(tail);
nonspace = ;
retval = EXIT_FAILURE;
}
//只要遇到空格和制表符,就先存起来
blank[head] = c;
head = advance(head);
}
else { //一次性把前面积攒的空格和制表符输出来
while (head != tail) {
putchar(blank[tail]);
tail = advance(tail);
}
putchar(c);
nonspace = ;
}
} 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 - )
return pointer + ;
else
return ;
} 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 = ; while ((c = getchar()) != EOF) {
if (c == '\n') {
head = tail = ;
if (spaceJustPrinted == ) /*if some trailing whitespace was printed...*/
retval = EXIT_FAILURE; if (nonspace) {
putchar('\n');
spaceJustPrinted = ; /* this instruction isn't really necessary since
spaceJustPrinted is only used to determine the
return value, but we'll keep this boolean
truthful */
nonspace = ; /* 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 = ;
tail = advance(tail);
nonspace = ;
} blank[head] = c;
head = advance(head);
}
else {
while (head != tail) {
putchar(blank[tail]);
tail = advance(tail);
}
putchar(c);
spaceJustPrinted = ;
nonspace = ;
}
} /* 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 == ) /*if some trailing whitespace was printed...*/
retval = EXIT_FAILURE; return retval;
}
c程序设计语言_习题1-18_删除输入流中每一行末尾的空格和制表符,并删除完全是空格的行的更多相关文章
- c程序设计语言_习题1-16_自己编写getline()函数,接收整行字符串,并完整输出
Revise the main routine of the longest-line program so it will correctly print the length of arbitra ...
- c程序设计语言_习题7-6_对比两个输入文本文件_输出它们不同的第一行_并且要记录行号
Write a program to compare two files, printing the first line where they differ. Here's Rick's solut ...
- c程序设计语言_习题8-4_重新实现c语言的库函数fseek(FILE*fp,longoffset,intorigin)
fseek库函数 #include <stdio.h> int fseek(FILE *stream, long int offset, int origin); 返回:成功为0,出错 ...
- c程序设计语言_习题8-6_利用malloc()函数,重新实现c语言的库函数calloc()
The standard library function calloc(n,size) returns a pointer to n objects of size size , with the ...
- c程序设计语言_习题1-19_编写函数reverse(s)将字符串s中字符顺序颠倒过来。
Write a function reverse(s) that reverses the character string s . Use it to write a program that re ...
- c程序设计语言_习题1-13_统计输入中单词的长度,并且根据不同长度出现的次数绘制相应的直方图
Write a program to print a histogram of the lengths of words in its input. It is easy to draw the hi ...
- c程序设计语言_习题1-11_学习单元测试,自己生成测试输入文件
How would you test the word count program? What kinds of input are most likely to uncover bugs if th ...
- c程序设计语言_习题1-9_将输入流复制到输出流,并将多个空格过滤成一个空格
Write a program to copy its input to its output, replacing each string of one or more blanks by a si ...
- 如何删除datatable中的一行数据
在C#中,如果要删除DataTable中的某一行,大约有以下几种办法: 1,使用DataTable.Rows.Remove(DataRow),或者DataTable.Rows.RemoveAt(ind ...
随机推荐
- 学习C++ Primer 的个人理解(二)
本身就一定基础的读者我想变量常量这些概念应该已经不是问题了.但是本章还是有几个重点,需要特别留意一下的: 1.初始化和赋值是不同的操作 2.任何非0值都是true 3.使用新标准列表初始化,在有丢失精 ...
- 九度OJ 1446 Head of a Gang -- 并查集
题目地址:http://ac.jobdu.com/problem.php?pid=1446 题目描述: One way that the police finds the head of a gang ...
- Linux中的安装神器--yum源安装
linux配置yum源 一.修改yum的配置文件 /etc/yum.repos.d/xxx.repo 1.进入yum配置文件目录 # cd /etc/yum.r ...
- 初识jQuery(适合初学者哟.........)
您要知道!! jQuery是目前使用最广泛的javascript函数库.据统计,全世界排名前100万的网站,有46%使用jQuery,远远超过其他库. 微软公司甚至把jQuery作为他们的官方库.对 ...
- ie6下 gif动画不动
ie6下 gif动画不动 如果有onclick事件:在IE6中,点击a标签,onclick事件会先执行,其次是href下的动作,href执行后,默认会执行跳转动作(尽管href属性不一定是一个地址), ...
- 转:testlink 环境搭建(傻瓜版)
testlink 环境搭建(傻瓜版) 2011-11-24 22:23 by 虫师, 12322 阅读, 4 评论, 收藏, 编辑 今天抽了点时间把testlink 环境搭建了一下,一直觉得这东西不怎 ...
- poj 2778 DNA Sequence ac自动机+矩阵快速幂
链接:http://poj.org/problem?id=2778 题意:给定不超过10串,每串长度不超过10的灾难基因:问在之后给定的长度不超过2e9的基因长度中不包含灾难基因的基因有多少中? DN ...
- C语言之指针
以32为系统为例. 1.指针与地址指针是一种变量,保存了所指向对象的地址.1.1 定义int i = 10;int *p = &i; //定义了一个指针p,它指向一个int型的变量&是 ...
- Oracle 排序分析函数之ROW_NUMBER、RANK和DENSE_RANK
我们都知道分析函数功能很强大,可能需要写很复杂的标准SQL才能办到或不可能办到的事,使用分析函数却能很容易完成.我们经常会用到排序分析函数,如ROW_NUMBER,RANK,DENSE_RANK.这三 ...
- codevs 1540 银河英雄传说
题目描述 Description 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米 ...