我从k& r学习C作为第一语言,我只是想问,如果你认为这个练习是以正确的方式解决的,我知道它可能不像你那么完整。我喜欢,但我想要观点,所以我知道我正在学习C。
由于
/* Exercise 1-22. Write a program to "fold" long input lines into two or
* more shorter lines, after the last non-blank character that occurs
* before then n-th column of input. Make sure your program does something
* intelligent with very long lines, and if there are no blanks or tabs
* before the specified column.
*
* ~svr
*
* [NOTE: Unfinished, but functional in a generic capacity]
* Todo:
* Handling of spaceless lines
* Handling of lines consisting entirely of whitespace
*/
#include <stdio.h>
#define FOLD 25
#define MAX 200
#define NEWLINE '\n'
#define BLANK ' '
#define DELIM 5
#define TAB '\t'
int
main(void)
{
int line = 0,
space = 0,
newls = 0,
i = 0,
c = 0,
j = 0;
char array[MAX] = {0};
while((c = getchar()) != EOF) {
++line;
if(c == NEWLINE)
++newls;
if((FOLD - line) < DELIM) {
if(c == BLANK) {
if(newls > 0) {
c = BLANK;
newls = 0;
}
else
c = NEWLINE;
line = 0;
}
}
array[i++] = c;
}
for(line = 0; line < i; line++) {
if(array[0] == NEWLINE)
;
else
printf("%c", array[line]);
}
return 0;
}
答案 0 :(得分:7)
我确信你在严谨的轨道上,但有一些可读性的指针:
if(array[0] != NEWLINE)
{
printf("%c", array[line]);
}
答案 1 :(得分:2)
这不是恕我直言。
首先,它没有按照您的要求进行操作。您应该在输出行边界之前的非空白之后找到最后一个空白。你的程序甚至没有远程尝试这样做,它似乎努力找到(margin-5)字符之后的第一个空白(5来自哪里?如果所有单词都有9个字母怎么办?)。但是它也没有这样做,因为你使用newls变量进行操作。另外,这个:
for(line = 0; line < i; line++) {
if(array[0] == NEWLINE)
;
else
printf("%c", array[line]);
}
可能是错误的,因为你检查的是一个在整个循环中永远不会改变的条件。
最后但并非最不重要的是,将整个文件存储在固定大小的缓冲区中并不好,原因有两个:
我认为你应该重新开始,重新考虑你的算法(包括角落案例),然后才开始编码。我建议你:
printf("%s", ...)
打印),将未打印的内容复制到缓冲区的开头,从那里开始答案 2 :(得分:0)
一个明显的问题是你静态分配'array'并且在访问它时从不检查索引限制。缓冲区溢出等待发生。事实上,你永远不会在第一个循环中重置i变量,所以我对程序应该如何工作感到困惑。看来你是在将完整的输入存储在内存中,然后再将其打印成文字包裹?
所以,建议:将两个循环合并在一起并打印已完成的每一行的输出。然后你可以重新使用数组作为下一行。
哦,更好的变量名称和一些评论。我不知道'DELIM'应该做什么。
答案 3 :(得分:0)
它看起来(没有测试)就像它可以工作,但它似乎有点复杂。
这是我第一次想到的伪代码
const int MAXLINE = ?? — maximum line length parameter
int chrIdx = 0 — index of the current character being considered
int cand = -1 — "candidate index", Set to a potential break character
char linebuf[bufsiz]
int lineIdx = 0 — index into the output line
char buffer[bufsiz] — a character buffer
read input into buffer
for ix = 0 to bufsiz -1
do
if buffer[ix] == ' ' then
cand = ix
fi
linebuf[lineIdx] = buffer[ix]
lineIdx += 1
if lineIdx >= MAXLINE then
linebuf[cand] = NULL — end the string
print linebuf
do something to move remnants to front of line (memmove?)
fi
od
已经很晚了,我只是有一个皮带,所以可能存在缺陷,但它显示了一般的想法 - 加载缓冲区,并将缓冲区的内容复制到行缓冲区,跟踪可能的断点。当你接近结束时,使用断点。