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