关于C#:为什么在编译K&R2第1章中最长的行示例时出现“ getline的类型冲突”错误?

Why do I get a “conflicting types for getline” error when compiling the longest line example in chapter 1 of K&R2?

这是我正在尝试直接从" C编程语言"的1.9节运行的程序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#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 != '
'
; ++i)
        s[i] = c;
    if (c == '
'
) {
        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;
}

这是我尝试使用Ubuntu 11.10编译程序时遇到的错误:

1
2
3
4
5
6
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等时,出现类似的错误。 当我无法运行程序以查看其输出时,真的很难学习。 在一个程序中引入字符数组和函数调用时,开始出现此问题。 我很乐意就此问题提出任何建议。


冲突的函数getline()是GNU / POSIX扩展。

K&R指出,他们在自己的书(c.f.)中专门针对ANSI C,但该书不提供此功能。

The authors present the complete guide to ANSI standard C language programming.

为了将gcc设置为" K&R兼容模式",您可以指定ANSI或ISO模式进行编译。这些旨在禁用扩展功能,例如功能getline()
这最终可以消除编辑K&R提供的其他示例的需要。

例如,以下编译就可以了:

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

(除了他们抱怨带有-Wallmain()的隐式默认返回类型。)

显然,在某些系统上,这些模式可能无法按此处介绍的方式工作(显然,某些版本的Mac OS无法正确禁用所有扩展名)。我在机器上成功测试了此:

1
2
3
4
5
$ 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.


问题是getline()是标准库函数。 (在stdio.h中定义)您的函数具有相同的名称,因此与此冲突。

解决方案是简单地更改名称。


这是因为stdio.h具有getline()功能。

因此,进行此工作的简单方法是将函数重命名为my_getline()

getline()getdelim()最初都是GNU扩展名。它们在POSIX.1-2008中进行了标准化。


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

那应该给你一个提示。尝试将代码中的getline()函数重命名为其他名称。

同样,以这种方式声明main()是旧样式。默认情况下,没有声明的返回类型和参数的函数接受未指定数量的参数并返回int。 main()几乎是这种情况:它确实返回一个int,但是有两个参数。您最好将其声明为:

1
int main(int argc, char **argv)

要么:

1
int main(int argc, char *argv[])


getline现在是在stdio.h中声明的POSIX函数

将您的getline函数重命名为另一个名称,它将进行编译。


您必须更改getline的名称,因为它已经存在。


的已经是在" stdio.h"文件中定义的名为getline的函数。因此原型冲突!
将您的函数重命名为" my_getline"或其他名称,一切都很好!