Почему я получаю ошибку "конфликтующие типы для getline" при компиляции примера самой длинной строки в главе 1 K & R2? - PullRequest
34 голосов
/ 06 января 2012

Вот программа, которую я пытаюсь запустить прямо из раздела 1.9 «Языка программирования C».

#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;
}

Вот ошибка, которую я получаю, когда пытаюсь скомпилировать программу с использованием 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

Просто чтобы убедиться, что это не проблема с печатным изданием в книге, я сослался на этот набор ответов на упражнения из задней части книги (http://users.powernet.co.uk/eton/kandr2/krx1.html), и я получаю аналогичную ошибку при попытке выполнить упражнения 18, 19, 20, 21 и т. Д. По этой ссылке. Действительно трудно понять, когда я не могу запустить программы, чтобы увидеть, как они выводятся. Эта проблема возникла при введении массивов символов и вызовов функций в одной программе. Буду признателен за любые советы по этому вопросу.

Ответы [ 7 ]

34 голосов
/ 06 января 2012

Проблема в том, что getline() является стандартной библиотечной функцией.(определено в stdio.h) Ваша функция имеет то же имя и поэтому конфликтует с ним.

Решение состоит в том, чтобы просто изменить имя.

33 голосов
/ 29 июня 2013

Конфликтующая функция getline() является расширением GNU / POSIX.

K & R заявляет, что они обращаются конкретно к ANSI C в своей книге (cf) , чтоне предоставляет эту функцию.

Авторы представляют полное руководство по программированию на языке стандарта ANSI C.

Чтобы установить gcc в "Режим совместимости с K & R", вы можете указатьрежимы ANSI или ISO для компиляции.Они предназначены для отключения расширений, например, функции getline().Это может в конечном итоге устранить необходимость редактирования других примеров, предоставляемых K & R.

Например, следующая компиляция просто отлично:

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

(За исключением того, что они жалуются на неявный возврат по умолчаниютип main() с -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.
9 голосов
/ 06 января 2012

Это потому, что stdio.h имеет функцию getline().

Итак, сделать эту работу проще всего - переименовать вашу функцию в my_getline()

И getline(), и getdelim() изначально были GNU расширениями. Они были стандартизированы в POSIX.1-2008.

3 голосов
/ 06 января 2012

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

Это должно дать вам подсказку.Попробуйте переименовать функцию getline() в коде во что-то еще.

Кроме того, объявление main() таким способом является старым стилем.Функция без объявленного возвращаемого типа и аргументов по умолчанию принимает неопределенное количество аргументов и возвращает int.Это почти так для main(): он возвращает int, но имеет два аргумента.Вам лучше объявить это как:

int main(int argc, char **argv)

или:

int main(int argc, char *argv[])
2 голосов
/ 06 января 2012

getline теперь является функцией POSIX, объявленной в stdio.h

Переименуйте функцию getline в другое имя, и она будет скомпилирована.

2 голосов
/ 06 января 2012

Вы должны изменить имя getline, потому что оно уже существует.

1 голос
/ 06 января 2012

Это уже функция с именем getline, определенная в файле "stdio.h". Таким образом, конфликт в прототипах! Переименуйте вашу функцию в «my_getline» или другое имя, и все должно быть в порядке!

...