40

これは、「Cプログラミング言語」のセクション1.9から直接実行しようとしているプログラムです。

#include <stdio.h>
#define MAXLINE 1000

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

main()
{
    int len;
    int max;
    char line[MAXLINE];
    char longest[MAXLINE];

    max = 0;
    while ((len = getline(line, MAXLINE)) > 0)
        if (len > max) {
        max = len;
        copy(longest, line);
        }
    if (max > 0)
        printf("%s", longest);
return 0;
}


int getline(char s[], int lim)
{
    int c, i;

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


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

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

Ubuntu11.10を使用してプログラムをコンパイルしようとするとエラーが発生します。

cc     word.c   -o word
word.c:4:5: error: conflicting types for ‘getline’
/usr/include/stdio.h:671:20: note: previous declaration of ‘getline’ was here
word.c:26:5: error: conflicting types for ‘getline’
/usr/include/stdio.h:671:20: note: previous declaration of ‘getline’ was here
make: *** [word] Error 1

本の印刷に問題がないことを確認するために、この本の章の裏側の演習の回答セットを参照しました(http://users.powernet.co.uk/eton/kandr2/krx1)。 html)と、そのリンクから演習18、19、20、21などを実行しようとすると、同様のエラーが発生します。プログラムを実行して出力を確認できない場合、学習するのは非常に困難です。この問題は、1つのプログラムに文字配列と関数呼び出しを導入したときに始まりました。この問題についてアドバイスをいただければ幸いです。

4

7 に答える 7

42

問題は、それgetline()が標準ライブラリ関数であるということです。(で定義されてstdio.hいます)あなたの関数は同じ名前を持っているので、それと衝突しています。

解決策は、単に名前を変更することです。

于 2012-01-06T19:09:25.400 に答える
42

競合する関数getline()はGNU/POSIX拡張機能です。

K&Rは、この機能を提供していない本(cf)でANSICを具体的に扱っていると述べています。

著者は、ANSI標準C言語プログラミングの完全なガイドを提示します。

gccを「K&R互換モード」に設定するために、コンパイル用のANSIまたはISOモードを指定できます。これらは、関数などの拡張機能を無効にすることを目的としていますgetline()。これにより、最終的にはK&Rが提供する他の例も編集する必要がなくなります。

たとえば、次のコンパイルは問題ありません。

$ gcc test.c -ansi
$ gcc test.c -std=c89

main()( withの暗黙的なデフォルトの戻りタイプについて文句を言うことを除いて-Wall。)

一部のシステムでは、これらのモードがここに示されているように機能しない場合があります(Mac OSの一部のバージョンではすべての拡張機能を正しく無効にできないようです)。私は自分のマシンでこれを正常にテストしました:

$ gcc --version
gcc (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8)
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
于 2013-06-29T08:53:06.873 に答える
10

これは、が機能stdio.hを持っているためgetline()です。

したがって、これを機能させる簡単な方法は、関数の名前を次のように変更することです。my_getline()

getline()とはgetdelim()元々GNU拡張機能でした。それらはで標準化されましたPOSIX.1-2008

于 2012-01-06T19:10:56.043 に答える
4

/usr/include/stdio.h:671:20: note: previous declaration of ‘getline’ was here

それはあなたにヒントを与えるはずです。getline()コード内の関数の名前を別の名前に変更してみてください。

また、このように宣言main()するのは古いスタイルです。戻り型と引数が宣言されていない関数は、デフォルトでは、不特定の数の引数を受け入れ、intを返します。これはほぼ当てはまりmain()ます:intを返しますが、2つの引数があります。次のように宣言することをお勧めします。

int main(int argc, char **argv)

また:

int main(int argc, char *argv[])
于 2012-01-06T19:10:33.547 に答える
2

getlineの名前はすでに存在するため、変更する必要があります。

于 2012-01-06T19:10:15.193 に答える
2

getlineで宣言されたPOSIX関数になりましたstdio.h

関数の名前getlineを別の名前に変更すると、コンパイルされます。

于 2012-01-06T19:11:03.227 に答える
1

はすでに「stdio.h」ファイルで定義されているgetlineと呼ばれる関数です。したがって、プロトタイプの競合!関数の名前を「my_getline」または他の名前に変更すると、すべて問題ないはずです。

于 2012-01-06T19:12:25.353 に答える