unable to compile C program with getline() using gcc

Discussion in 'Mac Programming' started by l0uismustdie, Jan 15, 2012.

  1. macrumors regular

    #1
    Hello, I am trying to run a C program using getline() and am receiving the following error message:
    Code:
    14:42@***:~/Documents/c$ gcc -o 3n1 3n1.c 
    Undefined symbols:
      "_getline", referenced from:
          _main in ccMhB6EQ.o
    ld: symbol(s) not found
    collect2: ld returned 1 exit status
    
    The program is as simple as possible:
    Code:
    #include <stdio.h>
    
    main()
    {
      int x;
      char *line;
    
      x = getline(line,100,stdin);
    }
    
    I used the definition from getline() on this site: https://wiki.cs.columbia.edu:8443/display/res/getline()+missing
    placed this in a getline.c file and included the getline.c file in my program and this resulted in a segmentation fault upon execution.

    Thanks to anyone who can point me in the right direction.
     
  2. robvas, Jan 15, 2012
    Last edited by a moderator: Jan 15, 2012

    macrumors 68000

    #2
    getline is included in OS X (at least it is in Lion, that page may have been from 'the old days')

    From a Terminal type 'man getline'
    Code:
    NAME
         getdelim, getline -- get a line from a stream
    
    LIBRARY
         Standard C Library (libc, -lc)
    
    SYNOPSIS
         #include <stdio.h>
    
         ssize_t
         getdelim(char ** restrict linep, size_t * restrict linecapp, int delimiter,
             FILE * restrict stream);
    
         ssize_t
         getline(char ** restrict linep, size_t * restrict linecapp, FILE * restrict stream);
    
    EXAMPLES
         The following code fragment reads lines from a file and writes them to standard output.  The
         fwrite() function is used in case the line contains embedded NUL characters.
    
               char *line = NULL;
               size_t linecap = 0;
               ssize_t linelen;
               while ((linelen = getline(&line, &linecap, fp)) > 0)
                       fwrite(line, linelen, 1, stdout);
    
    
    Per the man page, it looks like your first two arguments to the function are not right.
     
  3. macrumors regular

    #3
    Hmm...this may be the case. I am running Snow Leopard though.
    Code:
    15:57@***:~/Documents/c$ man getline
    No manual entry for getline
    
     
  4. macrumors 68000

    #4
    Are you allocating the pointer any memory to hold the input data?

    http://members.shaw.ca/ipatters/BeginC_9.html
     
  5. macrumors 601

    Mr. Retrofire

    #5
    man stdio

    tells us, that this function is not available in the Standard C lib (10.6.x). So write your own or use this:
    getdelim.c
    and
    getline.c
    from
    http://www.opensource.apple.com/source/cvs/cvs-42/cvs/lib/
    (contains other interesting parts)

    Should work without problems. Most configure scripts of open source programs check the availability of getline, which is the reason, why you see no GCC errors regarding getline in most cases.

    :)
     
  6. macrumors 6502

    #6
    It looks like you have to allocate the buffer for the line yourself. So change your code to

    Code:
    #include <stdio.h>
    #define MAX_LINE 100
    
    int main(void)
    {
      int x;
      char line[MAX_LINE];
    
      x = getline(line, MAX_LINE, stdin);
      return 0;
    }
    You were getting a segmentation fault because the getline() function you added to your program assumed that the buffer passed to it for it to fill was allocated by you beforehand. Instead, it was trying to poke the characters in no man's land.
     
  7. macrumors G5

    gnasher729

    #7
    "line" is an unitialised variable. This isn't going to work. If you are a beginner, you should say so to get help appropriate to your level. If you are not a beginner, what do you think is going to happen when getline stores a line of text where that uninitialised variable points to? A crash is the best thing that can happen.
     
  8. macrumors 6502a

    AlecZ

    #8
    This is exactly what made it work for me in Snow Leopard. Many thanks. I wish Snow Leopard could have its libraries updated, though! I mean, there's probably SOME way...
     
  9. macrumors 68000

    #9
    not sure what I was thinking in 2012 but you should have been able to do

    Code:
    gcc -o 3n1 3n1.c getline.c
    and have that work!
     
  10. denniscote, May 30, 2015 at 10:05 AM
    Last edited: May 30, 2015 at 10:08 AM

    macrumors newbie

    #10
    Please read the man page more carefully

    You are correct about the first two arguments being wrong, but some of the later suggestions are also wrong.

    Getline() can use a buffer supplied by the caller, or it can allocate a buffer and return it to the caller. If the user supplies a buffer, it must be a malloc'd buffer (not a fixed char array) since it may need to be realloc'd if the line is longer than the supplied buffer. It's probably easier to let getline() allocate the buffer. You indicate this by passing in the address of a NULL pointer.

    The docs say that getline() wants a char**, the address of a buffer pointer, and a size_t *, the address of a buffer length variable. It will read the line and update the buffer pointer to point at the new line buffer (which it has allocated) and set the capacity variable to the length of the buffer it has allocated. These are both output variables from getline(), so it needs the address of the caller's variables so it can update them.

    Code:
    getline(&line, &linecap, fp)
    
    In the example code they pass the address of the local variables line and linecap. Note that the line variable was initialized to NULL before calling getline(). Getline() will allocate a buffer, read the line, and return the length of the line it read (or an error code). Before returning it will update the caller's buffer pointer and buffer length variables.

    Once getline() has allocated a buffer, that same buffer can be passed back in to subsequent calls where its contents will be overwritten.

    To prevent a memory leak the allocated buffer must be free'd by the caller when it is done with it. This isn't done in the example code, but there should be a free(line) call after the loop ends.

    HTH
    Dennis Cote
     

Share This Page