K& R练习1-18(C编程语言)的意外输出

时间:2014-11-23 21:41:25

标签: c kernighan-and-ritchie

我对编程很陌生,所以请耐心等待。

以下是练习1-18的提示:编写程序以从每行输入中删除尾随空白和制表符,并删除完全空行。

这是我的代码:

#include <stdio.h>

#define MAXLINE 1000

int better_line_length(char line[], int lim);
void copy(char to[], char from[]);

int main(void)
{
    int len, a;
    char s[MAXLINE];
    char better_s[MAXLINE];

    while ((better_line_length(s, MAXLINE)) > 0) {
            copy(better_s, s);
            printf("%s\n", better_s);
        }

    return 0;
}

int better_line_length(char s[], int lim)
{
    int c, i, last_letter = 0;

    for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i) {
        s[i] = c;
        if (c != ' ' && c != '\t')
            last_letter = i+1;
    }
    if (c == '\n' && s[0] == c)
        last_letter = 0;

    s[last_letter] = '\0';

    return last_letter;
}

void copy(char to[], char from[]) 
{
    int i = 0;

    while ((to[i] = from[i]) != '\0')
        ++i;
}

我的程序没有给我预期的输出。在没有空行的情况下,它可以正确地删除尾随空白和制表符,但是当存在空行时,事情会变得奇怪。

例如,如果我的输入是(其中▯▯▯是空格)

abcdefg▯▯▯▯▯▯▯▯▯▯▯▯
1234▯▯▯▯▯

我得到

的预期输出
abcdefg
1234

但如果我的输入类似于

abcdefg▯▯▯▯▯▯▯▯▯▯▯▯
1234▯▯▯▯▯

xyz▯▯▯▯▯▯
987▯▯▯▯▯

我得到

的输出
abcdefg
1234

但我希望输出

abcdefg
1234
xyz
987

似乎我的while语句while ((better_line_length(s, MAXLINE)) > 0)main()在遇到空行而不是仅仅跳过它时停止执行。我已经花了好几个小时,我仍然无法弄清楚原因。我认为如果一行的第一个字符是better_line_length,那么将'\n'设置为返回0将修复代码,但它不会改变任何内容。

为什么我遇到这种意外的输出,为什么上述想法没有解决我的程序?

请记住,K&amp; R在第1章之前没有介绍某些高级主题,所以指针和某些其他主题对我来说还没有意义。

谢谢!

2 个答案:

答案 0 :(得分:2)

我发现你还在努力解决这个问题。对你有好处,不要放弃!

对于当前解决方案的问题:您可以做的一件事是您可以修改better_line_length()函数以返回意味着存在空行并在while ((len = better_line_length(s, MAXLINE)) > 0)循环内跳过该行的内容。 / p>

例如,您可以在better_line_length()循环之后的for正文中添加以下内容:

if(i == 0 && c == '\n')
  return -1;

然后你会知道这是你需要跳过的那一行。您还可以添加类似的返回代码,这意味着stdin的文件/结尾。

如果您需要更多帮助,请与我们联系。

答案 1 :(得分:1)

仔细看看你提到的那条线:

while ((better_line_length(s, MAXLINE)) > 0) {

如果函数better_line_length()返回0,则条件为假,循环结束。 这就是它放弃第一个空白线的原因。

当你真的到达终点或只是一个空白行时,你应该考虑回复一些不同的东西。

当你到达输入的末尾时,你可能(例如)返回-1。