undefined reference to `getline' in c
Asked Answered
B

4

24

I am learning to use getline in C programming and tried the codes from http://crasseux.com/books/ctutorial/getline.html

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int atgc, char *argv[])
{
    int bytes_read = 1;
    int nbytes = 10;
    char *my_string;

    my_string = (char *)malloc(nbytes+1);

    puts("Please enter a line of text");

    bytes_read = getline(&my_string, &nbytes, stdin);

    if (bytes_read == -1)
    {
        puts ("ERROR!");
    }
    else
    {
        puts ("You typed:");
        puts (my_string);
    }

    return 0;
 }

However, the problem is that the compiler keeps returning errors of this: undefined reference to 'getline'. Could you please tell me what the problem is? Thank you!

I am using Win7 64bit + Eclipse Indigo + MinGW

Barneybarnhart answered 28/10, 2012 at 20:37 Comment(2)
Have you tried compiling with -std=gnu90?Michaelmichaela
This is not a good C tutorial, or rather not a C tutorial at all. I would not recommend using it as your only or main source of information about C.Excrescent
N
21

The other answers have covered most of this, but there are several problems. First, getline() is not in the C standard library, but is a POSIX 2008 extension. Normally, it will be available with a POSIX-compatible compiler, as the macros _POSIX_C_SOURCE will be defined with the appropriate values. You possibly have an older compiler from before getline() was standardized, in which case this is a GNU extension, and you must #define _GNU_SOURCE before #include <stdio.h> to enable it, and must be using a GNU-compatible compiler, such as gcc.

Additionally, nbytes should have type size_t, not int. On my system, at least, these are of different size, with size_t being longer, and using an int* instead of a size_t* can have grave consequences (and also doesn't compile with default gcc settings). See the getline manual page (http://linux.die.net/man/3/getline) for details.

With that change made, your program compiles and runs fine on my system.

Nitwit answered 28/10, 2012 at 22:53 Comment(3)
Does it get standardized now? after 9 years.Viscountess
@VimNing Nope. still not in the standard lib, but at least they're on the TR block now. Brick by brick... (and a whole lot of sitting on asses doing nada).Southerner
@Viscountess The time it takes for C to standardize things is generally speaking measured in decades.Legge
R
10

I am also using MinGW. I checked MinGW headers and getline() does not appear in any C header, it appears only in C++ headers. This means the C function getline() does not exist in MinGW.

Rivulet answered 17/3, 2016 at 16:39 Comment(0)
G
8

getline isn't a standard function, you need to set a feature test macro to use it, according to my man page,

_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700

for glibc 2.10 or later,

_GNU_SOURCE

before that.

Godunov answered 28/10, 2012 at 20:43 Comment(0)
E
2

getline() is not in the C standard library. However, you may still use it with compiler flag -std=gnu99. This flag, telling the compiler to use the GNU dialect of ISO C99, is supported by both gcc and clang.

gcc main.c -std=gnu99

See gcc flags.

The manual (obtained by man getline in terminal) also says that

       getline(), getdelim():
           Since glibc 2.10:
               _POSIX_C_SOURCE >= 200809L
           Before glibc 2.10:
               _GNU_SOURCE

So you may add #define _POSIX_C_SOURCE 200809L or #define _GUN_SOURCE to your file to expose the declaration.

If you fancy, here is a basic implementation of getline()

ssize_t getline(char **restrict lineptr, size_t *restrict n,
        FILE *restrict stream) {

    register char c;
    register char *cs = NULL;
    register int length = 0;
    while ((c = getc(stream)) != EOF) {
        cs = (char *)realloc(cs, ++length + 1);
        if ((*(cs + length - 1) = c) == '\n') {
            *(cs + length) = '\0';
            break;
        }
    }

    // return the allocated memory if lineptr is null
    if ((*lineptr) == NULL) {
        *lineptr = cs;
    } 
    else {
        // check if enough memory is allocated 
        if ((length + 1) < *n) {
            *lineptr = (char *)realloc(*lineptr, length + 1);
        }
        memcpy(*lineptr, cs, length);
        free(cs);
    }
    return (ssize_t)(*n = strlen(*lineptr));
}

Exanthema answered 28/10, 2012 at 20:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.