K&安培; - [R练习:我的code工作,但感觉臭;建议对清理? [英] K & R Exercise: My Code Works, But Feels Stinky; Advice for Cleanup?

查看:116
本文介绍了K&安培; - [R练习:我的code工作,但感觉臭;建议对清理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作了K&放大器; R书。我读过放远一点,比我做过的练习,主要是由于缺乏时间。我赶上了,已经从第1章,这是本教程做了几乎所有的演习。

I'm working on the K&R book. I've read farther ahead than I've done exercises, mostly for lack of time. I'm catching up, and have done almost all the exercises from chapter 1, which is the tutorial.

我的问题是锻炼1-18。这次演习是:

My issue was exercise 1-18. The exercise is to:

编写一个程序,删除尾随空格和
  从输入制表符,并完全删除空行

Write a program to remove trailing blanks and tabs from line of input, and to delete entirely blank lines

我的code(下)这样做,和作品。我与它的问题是修剪方法,我实现。这种感觉......错了...不知何故。就像如果我看到在C#中类似code在code检讨,我可能会疯掉。 (C#是我的专业之一。)

My code (below) does that, and works. My problem with it is the trim method I implemented. It feels ... wrong ... somehow. Like if I saw similar code in C# in a code review, I'd probably go nuts. (C# being one of my specialties.)

任何人都可以提供在清理这个了一些建议 - 用听清楚说的建议有仅使用知识从K&安培第1章; R.(我知道有无数个方法来打扫一下使用完整的C库;我们讨论的只是第1章这里基本stdio.h中)此外,给予的建议时,你能解释一下为什么它会帮助? (我,毕竟,努力学习!还有谁更好地从比这里的专家学习?)

Can anyone offer some advice on cleaning this up -- with the catch that said advice has to only use knowledge from Chapter 1 of K & R. (I know there are a zillion ways to clean this up using the full C library; we're just talking Chapter 1 and basic stdio.h here.) Also, when giving the advice, can you explain why it will help? (I am, after all, trying to learn! And who better to learn from than the experts here?)

#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;
        }
    }
}

编辑:我AP preciate所有有用的提示,我在这里看到的。我想提醒的是,我仍然用C的n00b,特别是还没有起床的指针尚未乡亲。 (记住K&放大器的第1章位; R - 第1章不做指针。)I还挺得到一些这些解决方案,但他们仍然是一个触摸推进了我在哪里..

I appreciate all the helpful tips I'm seeing here. I would like to remind folks that I'm still a n00b with C, and specifically haven't gotten up to pointers yet. (Remember the bit about Ch.1 of K&R -- Ch.1 doesn't do pointers.) I "kinda" get some of those solutions, but they're still a touch advanced for where I'm at ...

和大部分东西我要找的是修剪方法本身 - 尤其是事实,我通过循环 3 倍(这感觉这么脏)。我觉得,如果我只是一个触摸更聪明(即使没有C的高级知识),这可能是更清洁。

And most of what I'm looking for is the trim method itself -- specifically the fact that I'm looping through 3 times (which feels so dirty). I feel like if I were just a touch more clever (even without the advanced knowledge of C), this could have been cleaner.

推荐答案

有没有理由有两个缓冲区,可以修剪到位输入行

There is no reason to have two buffers, you can trim the input line in place

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;
}

通过返回线路长度,可以通过测试非零长度线来消除空白行

By returning the line length, you can eliminate blank lines by testing for non-zero length lines

if (trim(line) != 0)
    printf("%s\n", line);

编辑:您可以使while循环更简单,假设ASCII编码

You can make the while loop even simpler, assuming ASCII encoding.

while (len > 0 && line[len-1] <= ' ')
    line[--len] = 0;

这篇关于K&安培; - [R练习:我的code工作,但感觉臭;建议对清理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆