2

I am going through K&R (2 ed.) to learn C as I've been trying to get a basis in lower-level languages to help my programming and also because I want to know C. The book is absolutely fantastic; however, a program they provided on pp. 29 (Sec 1.9 Character Arrays) does not compile. This is the code

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

When I run cc longest_line.c (that's what I called it) I get an error that getline has conflicting definitions as it was already defined in stdio.h. My question is, how do I resolve this/can I resolve this without giving getline a different name?

KevinDTimm
  • 14,226
  • 3
  • 42
  • 60
Eli Sadoff
  • 7,173
  • 6
  • 33
  • 61
  • 2
    For your reference [this is the `getline`](http://man7.org/linux/man-pages/man3/getline.3.html) declared in ``. As for your problem there is no solution other than to rename your function, you can not have two symbols with the same name and two differing declarations. – Some programmer dude Jun 22 '16 at 13:53
  • 3
    You can change your operating system to a non-posix flavor or you can rename the function. One of them is fastest. – Hans Passant Jun 22 '16 at 13:55
  • 1
    1) C does not support _methods_, only _functions_ 2) K&R teaches an outdated, non-standard compliant version of the C language. Use a more recent book. – too honest for this site Jun 22 '16 at 13:56
  • 1
    @Olaf is there a real difference between *method*s and *function*s? I've generally heard that they were interchangeable. – Eli Sadoff Jun 22 '16 at 13:57
  • If this conflict exists then why is it in the book.Was't it tested before going into the book. – Gaurav Sehgal Jun 22 '16 at 13:58
  • @HansPassant is there anyway I can have my OS compile with a non-POSIX style compiler w/o changing my OS to a non-POSIX OS? – Eli Sadoff Jun 22 '16 at 13:58
  • Don't use the same name as standard libray names. What is the problem with simply renaming that function, e.g. to `my_getline`? – too honest for this site Jun 22 '16 at 13:58
  • 1
    @GauravSehgal: 1) `getline` is POSIX, not C 2) K&R is simply outdated. – too honest for this site Jun 22 '16 at 13:59
  • @Olaf I know that's possible, that's not what I'm asking. I'm asking if there is a way to still call the function `getline`. – Eli Sadoff Jun 22 '16 at 13:59
  • @EliSadoff: That is a matter of the library, not the compiler. Just rename and stop trying to outsmart your toolchain! – too honest for this site Jun 22 '16 at 13:59
  • @xvan I'm using the second edition. (ANSI-C) – Eli Sadoff Jun 22 '16 at 14:01
  • @EliSadoff: C89/90 is not standard since 17 years now. – too honest for this site Jun 22 '16 at 14:03
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/115315/discussion-between-eli-sadoff-and-olaf). – Eli Sadoff Jun 22 '16 at 14:04
  • CV for typo. Childish "but I don't want to rename it" leads nowhere. – too honest for this site Jun 22 '16 at 14:04
  • And instead of `copy`, use `strcpy` or one of its relatives. If that is from the book: this is another example of outdated code, as `from` should be `const char from[]`. Today focus on programming has shifted twards quality. Even more for unsafe languages like C. – too honest for this site Jun 22 '16 at 14:14
  • Why are you trying to learn C from a book published in 1988? It's a historical curiosity. Put it on a shelf and get a book that covers the modern language. – Rob K Jun 22 '16 at 15:00
  • In my copy of Kernighan & Ritchie (1st edition), the code in section 1.9 does not include the statement `#include `. This is an early chapter in the book and I believe the authors are illustrating their point by including code that would become part of the standard libraries. Try compiling it without the `#include ` . – Blackwood Jun 22 '16 at 22:16

2 Answers2

2

As @Olaf commented, getline() is standard POSIX,

K&R second edition is ansi 89 standard.

Just compile in ansi mode, to prevent the collision with POSIX libraries:

gcc -ansi source.c

Edit: GodBot Link

xvan
  • 4,554
  • 1
  • 22
  • 37
  • What's your toolchain, the code compiles on (x86 gcc), tested multiple gcc versions from 4.8 to 6.1 – xvan Jun 22 '16 at 14:12
  • gcc: 4.2.1 and LLVM: 7.3.0 – Eli Sadoff Jun 22 '16 at 14:15
  • I tried on my computer in both `gcc-4.8` and `gcc-6` but it still doesn't compile. – Eli Sadoff Jun 22 '16 at 14:22
  • Try a newer compiler 4.2.1 is from 2008, I don't know the proper flags on that version, probably you need something else to explicitly disable posix, the earliest I was able to test on godbot is 4.4.7 – xvan Jun 22 '16 at 14:22
  • 1
    This is as far as I can help, something may be wrong with your toolchains. At least on linux x64, it works ok for me. – xvan Jun 22 '16 at 14:25
  • Thanks for your help! I'm going to accept your answer because despite it not working for me, it seems like it should work. – Eli Sadoff Jun 22 '16 at 14:26
-2

This approach avoids your problem by not including the problematic header. Rather, it copies all the declarations needed in your implementation locally.
This is a very bad idea because the declarations of these functions may change without your knowledge in which case your code will pass or receive bad inputs

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

~

Ishay Peled
  • 2,783
  • 1
  • 23
  • 37