K&R Error: конфликтующее определение метода

Я прохожу K&R (2-е изд.), чтобы изучить C, так как я пытался получить основу для языков более низкого уровня, чтобы помочь мне в программировании, а также потому, что я хочу знать C. Книга абсолютно фантастическая; однако программа, представленная на стр. 29 (раздел 1.9 «Массивы символов»), не компилируется. это код

#include <stdio.h>
#define MAXLINE 1000    /* maximum input line size */

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

/* print longest input line */
main()
{
    int len;            /* current line length */
    int max;            /* maximum length seen so far */
    char line[MAXLINE];     /* current input line */
    char longest[MAXLINE];  /* longest line saved here */

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

/* getline:  read a line int s, return length */
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;
}

/* copy:  copy 'from' into 'to'; assume to is big enough */
void copy(char to[], char from[])
{
    int i;

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

Когда я запускаю cc longest_line.c (так я его назвал), я получаю сообщение об ошибке, что getline имеет конфликтующие определения, так как он уже был определен в stdio.h. У меня вопрос: как решить эту проблему/могу ли я решить эту проблему, не давая getline другого имени?


person Eli Sadoff    schedule 22.06.2016    source источник
comment
Для справки: это getline, объявленное в <stdio.h>. Что касается вашей проблемы, то нет другого решения, кроме как переименовать вашу функцию, у вас не может быть двух символов с одинаковым именем и двух разных объявлений.   -  person Some programmer dude    schedule 22.06.2016
comment
Вы можете изменить свою операционную систему на версию, отличную от posix, или вы можете переименовать функцию. Один из них самый быстрый.   -  person Hans Passant    schedule 22.06.2016
comment
1) C не поддерживает методы, только функции 2) K&R обучает устаревшей, несовместимой со стандартом версии языка C. Используйте более новую книгу.   -  person too honest for this site    schedule 22.06.2016
comment
@Olaf Олаф, есть ли реальная разница между методами и функциями? Я вообще слышал, что они взаимозаменяемы.   -  person Eli Sadoff    schedule 22.06.2016
comment
Если этот конфликт существует, то почему он описан в книге? Разве он не был проверен перед тем, как попасть в книгу?   -  person Gaurav Sehgal    schedule 22.06.2016
comment
@HansPassant в любом случае, я могу скомпилировать свою ОС с помощью компилятора, отличного от POSIX, без изменения моей ОС на ОС, отличную от POSIX?   -  person Eli Sadoff    schedule 22.06.2016
comment
Не используйте то же имя, что и стандартные имена библиотек. В чем проблема с простым переименованием этой функции, например. в my_getline?   -  person too honest for this site    schedule 22.06.2016
comment
@GauravSehgal: 1) getline - это POSIX, а не C 2) K&R просто устарел.   -  person too honest for this site    schedule 22.06.2016
comment
@ Олаф, я знаю, что это возможно, я не об этом спрашиваю. Я спрашиваю, есть ли способ по-прежнему вызывать функцию getline.   -  person Eli Sadoff    schedule 22.06.2016
comment
@EliSadoff: это вопрос библиотеки, а не компилятора. Просто переименуйте и перестаньте пытаться перехитрить свою цепочку инструментов!   -  person too honest for this site    schedule 22.06.2016
comment
@xvan Я использую второе издание. (АНСИ-С)   -  person Eli Sadoff    schedule 22.06.2016
comment
@EliSadoff: C89/90 не является стандартом уже 17 лет.   -  person too honest for this site    schedule 22.06.2016
comment
Давайте продолжим обсуждение в чате.   -  person Eli Sadoff    schedule 22.06.2016
comment
Резюме за опечатку. Детски, но я не хочу переименовывать это никуда не ведет.   -  person too honest for this site    schedule 22.06.2016
comment
И вместо copy используйте strcpy или один из его родственников. Если это из книги: это еще один пример устаревшего кода, так как from должно быть const char from[]. Сегодня акцент на программировании сместился в сторону качества. Еще больше для небезопасных языков, таких как C.   -  person too honest for this site    schedule 22.06.2016
comment
Почему вы пытаетесь выучить C по книге, опубликованной в 1988 году? Это историческое любопытство. Поставьте ее на полку и получите книгу, посвященную современному языку.   -  person Rob K    schedule 22.06.2016
comment
В моей копии Kernighan & Ritchie (1-е издание) код в разделе 1.9 не включает оператор #include <stdio.h>. Это первая глава книги, и я полагаю, что авторы иллюстрируют свою точку зрения, включая код, который станет частью стандартных библиотек. Попробуйте скомпилировать его без #include <stdio.h> .   -  person Blackwood    schedule 23.06.2016


Ответы (2)


Как прокомментировал @Olaf, getline() является стандартным POSIX,

Второе издание K&R соответствует стандарту ansi 89.

Просто скомпилируйте в режиме ansi, чтобы предотвратить конфликт с библиотеками POSIX:

gcc -ansi source.c

Edit: Ссылка на GodBot

person xvan    schedule 22.06.2016
comment
Какой у вас набор инструментов, код компилируется (x86 gcc), протестировано несколько версий gcc от 4.8 до 6.1. - person xvan; 22.06.2016
comment
gcc: 4.2.1 и LLVM: 7.3.0 - person Eli Sadoff; 22.06.2016
comment
Я пробовал на своем компьютере как gcc-4.8, так и gcc-6, но он все еще не компилируется. - person Eli Sadoff; 22.06.2016
comment
Попробуйте более новый компилятор 4.2.1 от 2008 года, я не знаю правильных флагов в этой версии, возможно, вам нужно что-то еще, чтобы явно отключить posix, самое раннее, что я смог протестировать на godbot, - это 4.4.7 - person xvan; 22.06.2016
comment
Насколько я могу помочь, что-то может быть не так с вашими наборами инструментов. По крайней мере на linux x64 у меня работает нормально. - person xvan; 22.06.2016
comment
Спасибо за вашу помощь! Я собираюсь принять ваш ответ, потому что, несмотря на то, что он не работает для меня, похоже, он должен работать. - person Eli Sadoff; 22.06.2016

Этот подход позволяет избежать вашей проблемы, не включая проблемный заголовок. Скорее, он копирует все объявления, необходимые в вашей реализации, локально.
Это очень плохая идея, потому что объявления этих функций могут измениться без вашего ведома, и в этом случае ваш код будет проходить или получать неверные входные данные.

#define MAXLINE 1000    /* maximum input line size */

int getline(char line[], int maxline);
void copy(char to[], char from[]);
int printf(const char *format, ...);
int getchar(void);

/* print longest input line */
int main()
{
    int len;            /* current line length */
    int max;            /* maximum length seen so far */
    char line[MAXLINE];     /* current input line */
    char longest[MAXLINE];  /* longest line saved here */

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

/* getline:  read a line int s, return length */
int getline(char s[], int lim)
{
    int c, i;

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

/* copy:  copy 'from' into 'to'; assume to is big enough */
void copy(char to[], char from[])
{
    int i;

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

~

person Ishay Peled    schedule 22.06.2016
comment
ОП хочет знать, может ли он избежать переименования getline. - person Gaurav Sehgal; 22.06.2016
comment
Я знаю это. Я спрашивал, могу ли я сохранить определение getline и каким-то образом переопределить определение stdio.h. - person Eli Sadoff; 22.06.2016
comment
Никогда не объявляйте функции стандартной библиотеки самостоятельно! На самом деле они могут быть макросами, иметь атрибуты, специфичные для реализации, и т. д. Используйте стандартные заголовки. ОП должна переименовать свою функцию. - person too honest for this site; 22.06.2016
comment
@Olaf, это конкретный пример и единственный возможный способ получить то, что хочет оператор, не все черное или белое. Там четко указано - person Ishay Peled; 22.06.2016
comment
@EliSadoff Это ответ на твой вопрос, Эли? - person Ishay Peled; 22.06.2016
comment
@IshayPeled: Как это меняет то, что я написал в своем комментарии? - person too honest for this site; 22.06.2016
comment
@ Олаф в том смысле, что я упоминаю проблему, которую вы упоминаете, но не пытаюсь кого-то просветить ... - person Ishay Peled; 22.06.2016
comment
Интересно, почему я получаю так много минусов. Правда, первый ответ был неверным и я не обратил внимания (поэтому его удалили). Но почему этот ответ был отклонен, если он работает, и я еще не видел здесь другого возможного решения. Это не относится к разделу комментариев, но это действительно раздражает. - person Ishay Peled; 22.06.2016
comment
@IshayPeled: В моем комментарии указана одна причина: вы учите плохой практике и, возможно, нарушаете интерфейс на целевой машине. - person too honest for this site; 22.06.2016
comment
Согласитесь, я ничему не учу - только решаю проблемы. Для этого и существует stackoverflow. - person Ishay Peled; 22.06.2016