我正在研究K&R书.我读的比我做的更进一步,主要是因为时间不够.我正赶上来,并完成了第1章的几乎所有练习,这是本教程.
我的问题是练习1-18.练习是:
编写程序以从输入行中删除尾随空白和制表符,并删除完全空行
我的代码(下面)做到了,并且有效.我的问题是我实施的修剪方法.感觉......错......不知何故.就像我在代码审查中看到C#中的类似代码一样,我可能会疯了.(C#是我的专长之一.)
任何人都可以提供一些关于清理它的建议 - 所述建议只能使用K&R第1章的知识.(我知道有很多方法可以使用完整的C库来清理它;我们'我只是在这里谈论第1章和基本的stdio.h.)另外,在给出建议时,你能解释它为什么会有用吗?(毕竟,我是在努力学习!谁比这里的专家更好地学习?)
#include#define MAXLINE 1000 int getline(char line[], int max); void trim(char line[], char ret[]); int main() { char line[MAXLINE]; char out[MAXLINE]; int length; while ((length = getline(line, MAXLINE)) > 0) { trim(line, out); printf("%s", out); } return 0; } int getline(char line[], int max) { int c, i; for (i = 0; i < max - 1 && (c = getchar()) != EOF && c != '\n'; ++i) line[i] = c; if (c == '\n') { line[i] = c; ++i; } line[i] = '\0'; return i; } void trim(char line[], char ret[]) { int i = 0; while ((ret[i] = line[i]) != '\0') ++i; if (i == 1) { // Special case to remove entirely blank line ret[0] = '\0'; return; } for ( ; i >= 0; --i) { if (ret[i] == ' ' || ret[i] == '\t') ret[i] = '\0'; else if (ret[i] != '\0' && ret[i] != '\r' && ret[i] != '\n') break; } for (i = 0; i < MAXLINE; ++i) { if (ret[i] == '\n') { break; } else if (ret[i] == '\0') { ret[i] = '\n'; ret[i + 1] = '\0'; break; } } }
编辑:我感谢我在这里看到的所有有用的提示.我想提醒大家,我仍然是一个带有C的n00b,特别是还没有达到指针.(记住关于K&R的Ch.1的一点 - 第1章没有指针.)我"有点"得到一些解决方案,但它们仍然是一个先进的触摸我...
我正在寻找的大多数是修剪方法本身 - 特别是我循环3次(感觉很脏)的事实.我觉得如果我只是一个更聪明的触摸(即使没有C的高级知识),这可能更清洁.
如果你坚持第1章,这看起来对我很好.以下是我从代码审查的角度推荐的内容:
在C中检查相等性时,始终先将常量置于其中
if (1 == myvar)
这样你就不会意外地做这样的事情:
if (myvar = 1)
你无法在C#中使用它,但它在C中编译得很好并且可能是一个真正的调试恶魔.
没有理由有两个缓冲区,您可以修改输入线
int trim(char line[]) { int len = 0; for (len = 0; line[len] != 0; ++len) ; while (len > 0 && line[len-1] == ' ' && line[len-1] == '\t' && line[len-1] == '\n') line[--len] = 0; return len; }
通过返回行长度,可以通过测试非零长度行来消除空行
if (trim(line) != 0) printf("%s\n", line);
编辑:假设ASCII编码,您可以使while循环更简单.
while (len > 0 && line[len-1] <= ' ') line[--len] = 0;