1

実際の質問については、この投稿の下部をご覧ください

本当に単純なことを理解しようとしているのかもしれませんが、これを理解するまで続けることはできません.

K&R 1.9 Character Arrays を読んでいると、入力を受け取り、どの行が最も長いかを判断して、それを再表示するサンプル プログラムに出くわします。

このプログラムの getline 関数を理解するために、進行中にいくつかの情報を表示するように少し変更しました。これで、getchar() の理解が大幅に深まることでしょう。


余談ですが、ライブラリからソース コードを読み取ろうとすると、完全に圧倒されてしまいます。たとえば、getchar() を#endif調べてみたところ、stddef.h の 300 行目のどこかにある 18 の塔を見て唖然としました。近い将来、stdio.h の関数の追求を中止することで、その頭痛を解消するつもりです。ライブラリが何かを見つけるのが非常に難しいのは普通ですか? 関数が読み取り可能なソースとして存在するべきではありませんか、それとも希望を持っているだけですか?


便宜上、変更したプログラム全体を K&R から投稿します。

#include <stdio.h>
#define MAXLINE 5   /* maximum input line length */

int getline(char line[], int maxline);
void copy(char to[], char from[]);

/* print the longest input line */
main()
{
    int len;            /* current line length */
    int max;            /* maximum length seen so far */
    char line[MAXLINE];    /* current input line */
    char longest[MAXLINE]; /* longest line saved here */
    max = 0;
    while ((len = getline(line, MAXLINE)) > 0)
        if (len > max) {
            max = len;
            copy(longest, line);
        }
    if (max > 0)  /* there was a line */
        printf("%s\n", longest);
        printf("INFO: max = %d\n", max);
        printf("INFO: sizeof s[] = %d", sizeof longest);
    return 0;
}

/* getline:  read a line into s, return length  */
int getline(char s[],int lim)
{
    int c, i;
    for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i){
        s[i] = c;
        printf("INFO: s[%d] = %c\n", i, c);
    if (c == '\n') {
        printf("INFO: %d\n", i);
        printf("INFO: s[%d] = \\n\n", i);
        s[i] = c;
        ++i;}
    }
    s[i] = '\0';
    return i;
}

/* copy:  copy ’from’ into ’to’; assume to is big enough */
void copy(char to[], char from[])
{
    int i;
    i = 0;
    while ((to[i] = from[i]) != '\0')
        ++i;
}

入力/出力の例を次に示します。 CodeBlocks と Windows 7 を使用しています。

サンプルIO

最後に、私の質問は、getline() 関数の for ループが到達後にループを離れ、その後にnullFターミネータを配置する理由です。F\0

私の仮説は、おそらく EOF 文字を^ZWindows 端末のように配置すると、配列は 4 文字と null ターミネータの長さに切り捨てられるということです。読み取る行の中に EOF 文字を入れると、保存された行には最大サイズ 5 しか含まれないことがわかります。また、変数が常に 0 になるs[]ことも混乱を招きます。 main() で、while ループが壊れると値が保存されませんか?lenlen

私にとっては興味深いことですが、経験豊富な C ユーザーにとってはおそらく興味深いことではありませんが、getline() の for ループの直後にある if ステートメントは、for ループの内側または外側のどちらでもかまいませんが、プログラムは変更されません。興味深いのは、for ループが本体内のコードを実行するかどうかに関係なく、少なくとも (c=getchar()) が実行されるということではないでしょうか?

質問が非常に冗長で申し訳ありませんが、役立つコメント/回答に感謝します。

4

1 に答える 1

6

MAXLINEは 5 であるため、この関数は 2文字getline以上読み取ることはありません。MAXLINE - 1

于 2012-11-12T08:18:34.053 に答える