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# DataTable 中 Select 和 Clone 用法结合
C# DataTable是存放数据的一个离线数据库,将数据一下加载到内存. DataTable.Select ()方法: Select();//全部查出来 Select(过滤条件);//根据过滤 ...
- 暑假集训(3)第一弹 -----还是畅通工程(hdu1233)
题意梗概:N(n<100)个村子想要富起来,自然就要先修路,不过到底还是没富起来,所以陷入了一个怪圈 :资金不足->修不起路->资金不足...... 为了实现走向全民小康社会,全面实 ...
- 最短路 dijkstra and floyd
二:最短路算法分析报告 背景 最短路问题(short-path problem):若网络中的每条边都有一个数值(长度.成本.时间等),则找出两节点(通常是源节点和阱节点)之间总权和最小的路径就是最短路 ...
- 学习C++ Primer 的个人理解(二)
本身就一定基础的读者我想变量常量这些概念应该已经不是问题了.但是本章还是有几个重点,需要特别留意一下的: 1.初始化和赋值是不同的操作 2.任何非0值都是true 3.使用新标准列表初始化,在有丢失精 ...
- How to debug Custom Action DLL
在MSI工程中,经常会遇到这样的情况: MSI 工程需要调用DLL(C++)中的一个函数实现某些特殊或者复杂的功能,通常的做法是在Custom Action 中调用该DLL . 那么在安装过程中,该C ...
- sgu 108 Self-numbers II
这道题难在 hash 上, 求出答案很简单, 关键是我们如何标记, 由于 某个数变换后最多比原数多63 所以我们只需开一个63的bool数组就可以了! 同时注意一下, 可能会有相同的询问. 我为了防止 ...
- Openstack 目录
[一] OpenStack 基础环境 [二] OpenStack 认证服务 KeyStone [三] OpenStack 镜像服务 Glance [四] OpenStack 计算服务 Nova [五] ...
- (转载)ADOQuery参数传递
ADOQuery参数传递 dbgrid1.DataSource := datasource1; datasource1.DataSet := adoquery1; Value := 1221; SQL ...
- 网络设备作用和工作ISO层
物理层——中继器和集线器 二者都起数字信号放大和中转的作用. 中继器 Repeater 用来延长网络距离的互连设备.REPEATER可以增强线路上衰减的信号,它两端即可以连接相同的传输媒体,也可以连接 ...
- win8.1系统下,点击一个窗口,【当前活动窗口】该窗口无法置顶
两个或多个窗口同时显示在桌面的时候,点击下一层的窗口,无法置顶显示,无论怎么点击,还是隐藏在原置顶窗口的后面,只能手动把原置顶窗口最小化后,才能看到.例如,A窗口现在置顶,B窗口在A的后面,露出来一部 ...