Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

Чтобы установить 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.

Ответ 3

Это связано с тем, что stdio.h имеет функцию getline().

Так просто, чтобы сделать эту работу, было бы переименовать вашу функцию в my_getline()

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

Ответ 4

/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[])

Ответ 5

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

Ответ 6

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

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

Ответ 7

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