1

Kernighan と Ritchies の ch1 問題 12 に答えるために、次のプログラムを作成しました。

問題は、関数を適切に使用する方法を本当に理解したことがなく、このプログラムに書いたgetcharc()が機能しない理由を知りたいということです。

関数の正しい使用法を説明する優れたリソースは何ですか。どこ?そしてどうやって?

||Richard Heathfield のサイト (ネストされた while ステートメントではなく orを使用) からこの問題の最適な解決策を知っていますが、プログラムを適切に動作させる方法を知りたいです。

#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

可能な解決策の 1 つは、関数のプロトタイプを に変更すること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()1 文字ずつ読み取るため、文字ごとに 1 回だけ実行されます。ここではネストされたループは必要ありません! に置き換えることで確認できwhileifコードは特定の文字列に対して同じ出力を提供します。ここで出力を参照してください。

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 に答える
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 に答える