1

我编写了以下程序来回答 Kernighan 和 Ritchies ch1 问题 12。

问题是我从来没有真正理解如何正确使用函数,想知道为什么我写进这个程序的getcharc()不起作用?

什么是解释正确功能使用的好资源。在哪里?如何?

我从 Richard Heathfield 的网站(它使用 or,而不是我使用的嵌套 while 语句)知道这个问题的最佳解决方案||,但是我想知道如何使我的程序正常工作:

#include <stdio.h>
int getcharc ();
// Exercise 1-12
// Copy input to output, one word per line
// words deleniated by tab, backspace, \ and space

int main()
{
    int c;

    while ((c = getchar()) != EOF) {
        while ( c == '\t') {
            getcharc(c);
        }
        while ( c == '\b') {
            getcharc(c);
        }
        while ( c == '\\') {
            getcharc(c);
        }
        while ( c == ' ') {
            getcharc(c);
        }
        putchar(c);
    }
}
int getcharc ()
{
    int c;

    c = getchar();
    printf("\n");
    return 0;
}

没有该功能的原始程序(我知道它有错误)是:

#include <stdio.h>

// Exercise 1-12
// Copy input to output, one word per line
// words deleniated by tab, backspace, \ and space

int main()
{
    int c;

    while ((c = getchar()) != EOF) {
        while ( c == '\t') {
            c = getchar();
            printf("\n");
        }
        while ( c == '\b') {
            c = getchar();
            printf("\n");
        }
        while ( c == '\\') {
            c = getchar();
            printf("\n");
        }
        while ( c == ' ') {
            c = getchar();
            printf("\n");
        }
        putchar(c);
    }
}

所以我试图用这个功能做的就是停止

c = getchar();
printf("\n");

每次都被重复。

4

3 回答 3

1

这个函数到底getcharc()应该做什么?它的作用是从输入中读取一个字符,打印一个换行符,然后返回零。刚刚从输入中读取的字符被丢弃,因为你没有对它做任何事情。当它被调用时,返回值也被忽略。在调用它的每个地方,您都在无限循环中调用它,因为没有为更改循环控制变量做出任何规定。

也许您打算使用类似的东西c = getcharc(),但这并没有真正的帮助,因为c无论如何您都没有从该函数返回。(好吧,无论如何,这将有助于“无限循环”部分。)

无论如何,这个功能有什么意义?如果你只是getchar()在它的位置正确使用,看起来你会有你的解决方案,除非有一些其他的错误。

于 2013-10-11T16:59:31.340 回答
0
// compiled by my brain muhahaha

#include <stdio.h>
int getcharc(); // we prototype getcharc without an argument

int main()
{
    int c; // we declare c

    // read character from stdio, if end of file quit, store read character in c
    while ((c = getchar()) != EOF) {  
        // if c is tab \t call function getcharc() until forever since c never changes
        while ( c == '\t') { 
            getcharc(c); // we call function getcharc with an argument
            // however getcharc doesn't take an argument according to the prototype
        }
        // if c is \b call function getcharc() until forever since c never changes
        while ( c == '\b') {
            getcharc(c);
        }
        // if c is \\ call function getcharc() until forever since c never changes
        while ( c == '\\') {
            getcharc(c);
        }
        // if c is ' ' call function getcharc() until forever since c never changes
        while ( c == ' ') {
            getcharc(c);
        }
        // since we never will get here but if we happened to get here by some
        // strange influence of some rare cosmic phenomena print out c
        putchar(c);
    }
}

// getcharc doesn't take an argument
int getcharc ()
{
    int c;  // we declare another c

    c = getchar(); // we read from the keyboard a character
    printf("\n"); // we print a newline
    return 0; // we return 0 which anyway will never be read by anyone
}

也许你对旧的 K&R 感到困惑

如今,当您编写函数参数时,您可以像这样指定它

int getcharch(int c)
{
  ...
}
于 2013-10-11T18:03:22.697 回答
0

一种可能的解决方案是将函数的原型更改为int getcharc (int c, int flag).
现在你的代码经过一些修改;

#include <stdio.h>
int getcharc (int c, int flag);
// Exercise 1-12
// Copy input to output, one word per line
// words deleniated by tab, backspace, \ and space

int main()
{
    int c;
    int flag = 0;  //to keep track of repeated newline chars.

    while ((c = getchar()) != '\n') {
        flag = getcharc(c, flag);   // call getcharc() for each char in the input string. Testing for newline and printing of chars be done in the getcharc() function
    }
    return 0;     
}

int getcharc (int c, int flag)
{
        if( (c == ' ' || c == '\t' || c == '\b' || c== '\\')  && flag == 0)
        {
            printf("\n");
            flag = 1;
        }
        else
        {
            if(c != ' ' && c != '\t' && c != '\b' && c!= '\\')
                {
                     putchar(c);
                     flag = 0;
                }
        }
        return flag;
}

编辑:

但我想保留嵌套的 while 语句而不是使用 || 或者

您的嵌套 while 循环仅对每个字符执行一次,因为一次grtchar()读取一个字符。这里不需要嵌套循环!您可以通过替换while来检查它,if并且您的代码将为给定的字符串提供相同的输出。请参阅此处的输出。

从 Richard Heathfield 的网站(它使用 || 或者,而不是我使用的嵌套 while 语句)知道这个问题的最佳解决方案,但是我想知道如何使我的程序正常工作:

if您可以通过添加条件和break语句 来使您的程序在某种程度上(与您的错误)一起工作;

#include <stdio.h>
int getcharc (int c);

int main()
{
    int c;

    while ((c = getchar()) != '\n') {
        while ( c == '\t') {
            c = getcharc(c);
            if(c != '\t')
                break;
            }

        ....
        ....


        while ( c == ' ') {
            c = getcharc(c);
            if(c != ' ')
                break;
            }
        putchar(c);
    }
    return 0;
}
int getcharc (int c)
{
    c = getchar();
    printf("\n");
    return c;
}
于 2013-10-11T16:30:48.690 回答