在编译K&R2第1章中最长的行示例时,为什么会出现"getline的冲突类型"错误?

Sal*_*lar 34 c linux kernighan-and-ritchie

这是一个我试图直接从"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;
}
Run Code Online (Sandbox Code Playgroud)

这是我尝试使用Ubuntu 11.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
Run Code Online (Sandbox Code Playgroud)

为了确保书中的印刷品不是问题,我从书中引用了这组章节练习的答案(http://users.powernet.co.uk/eton/kandr2/krx1.当我尝试从该链接运行练习18,19,20,21等时,我得到类似的错误.当我无法运行程序以查看它们的输出时,真的很难学.在一个程序中引入字符数组和函数调用时,就会出现此问题.我对这个问题有任何建议表示感谢.

Mys*_*ial 35

问题是这getline()是一个标准的库函数.(定义stdio.h)您的函数具有相同的名称,因此与它发生冲突.

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

  • 在此浪费了20分钟.应该只是谷歌搜索 (6认同)
  • **getline()****不是**标准库函数,它是一个扩展,因为@moooeeeep更深入地说明了这里http://stackoverflow.com/questions/7376566/can-an-由@Dietrich Epp提供的符合ansi-c标准的实施 - 包含 - 附加功能.所以,如果你今天编写代码,你不应该使用`getline()`,但是如果你依赖于已经使用它自己实现的`getline()`函数的库呢?我认为,从广义上讲,@ moooeeeep的答案更合适. (2认同)

moo*_*eep 35

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

K&R声明他们在他们的书(cf)中专门针对ANSI C ,它不提供此功能.

作者提供了ANSI标准C语言编程的完整指南.

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

例如,以下编译就好了:

$ gcc test.c -ansi
$ gcc test.c -std=c89
Run Code Online (Sandbox Code Playgroud)

(除了他们抱怨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.
Run Code Online (Sandbox Code Playgroud)


San*_*raj 9

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

这样做的一个简单方法就是将你的函数重命名为 my_getline()

无论getline()getdelim()最初GNU的扩展.它们是标准化的POSIX.1-2008.