K&R 第 1 章 - 练习 22 的解决方案,你觉得怎么样?
我正在从 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;
}
I'm learning C from the k&r as a first language, and I just wanted to ask, if you thought this exercise was being solved the right way, I'm aware that it's probably not as complete as you'd like, but I wanted views, so I'd know I'm learning C right.
Thanks
/* 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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我确信你在正确的轨道上,但有一些可读性的提示:
I'm sure you on the rigth track, but some pointers for readability:
恕我直言,这不好。
首先,它不符合您的要求。 您应该在输出行边界之前的非空白之后找到最后一个空白。 你的程序甚至没有远程尝试这样做,它似乎努力寻找 (margin - 5) 个字符后的第一个空白(5 来自哪里?如果所有单词都有 9 个字母怎么办?)。 然而,由于您对 newls 变量的操作,它也不会这样做。 另外,这:
可能是错误的,因为您检查在整个循环中永远不会改变的条件。
最后但并非最不重要的一点是,将整个文件存储在固定大小的缓冲区中并不好,因为有两个原因:
我认为您应该重新开始,重新考虑您的算法(包括极端情况),然后才开始编码。 我建议您:
printf("%s", ...)
) 打印,将未打印的内容复制到缓冲区的开头,从那里继续That's no good IMHO.
First, it doesn't do what you were asked for. You were supposed to find the last blank after a nonblank before the output line boundary. Your program doesn't even remotely try to do it, it seems to strive for finding the first blank after (margin - 5) characters (where did the 5 came from? what if all the words had 9 letters?). However it doesn't do that either, because of your manipulation with the newls variable. Also, this:
is probably wrong, because you check for a condition that never changes throughout the loop.
And, last but not least, storing the whole file in a fixed-size buffer is not good, because of two reasons:
I think you should start again, rethink your algorithm (incl. corner cases), and only after that, start coding. I suggest you:
printf("%s", ...)
), copy what you didn't print to the start of the buffer, proceed from that一个明显的问题是您静态分配“数组”并且在访问它时从不检查索引限制。 缓冲区溢出等待发生。 事实上,您从未在第一个循环中重置 i 变量,所以我对程序应该如何工作感到有点困惑。 看来您在打印自动换行之前将完整的输入存储在内存中?
因此,建议:将两个循环合并在一起,并打印已完成的每一行的输出。 然后您可以在下一行中重新使用该数组。
哦,还有更好的变量名和一些注释。 我不知道“DELIM”应该做什么。
An obvious problem is that you statically allocate 'array' and never check the index limits while accessing it. Buffer overflow waiting to happen. In fact, you never reset the i variable within the first loop, so I'm kinda confused about how the program is supposed to work. It seems that you're storing the complete input in memory before printing it word-wrapped?
So, suggestions: merge the two loops together and print the output for each line that you have completed. Then you can re-use the array for the next line.
Oh, and better variable names and some comments. I have no idea what 'DELIM' is supposed to do.
看起来(未经测试)它可以工作,但似乎有点复杂。
这是我的第一个想法的一些伪代码
现在已经晚了,我只有一条腰带,所以可能存在缺陷,但它显示了总体思路 - 加载缓冲区,并将缓冲区的内容复制到行缓冲区,跟踪可能的情况断点。 当接近结尾时,使用断点。
It looks (without testing) like it could work, but it seems kind of complicated.
Here's some pseudocode for my first thought
It's late and I just had a belt, so there may be flaws, but it shows the general idea — load a buffer, and copy the contents of the buffer to a line buffer, keeping track of the possible break points. When you get close to the end, use the breakpoint.