Advertisement
drankinatty

C getln (getline substitute using fgetc)

May 17th, 2015
455
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.71 KB | None | 0 0
  1. #define SZINIT 120
  2.  
  3. /** getln reads up to n characters from stream into s, (if n=0 no limit).
  4.  *  Reading continues until n characters read (or newline or EOF reached).
  5.  *  s is initially reallocated n (or SZINIT, if n=0) + 1 bytes. (no overrun).
  6.  *  If n=0, s is reallocated as needed to read an entire line. A final call
  7.  *  to realloc trims the amount of memory allocated only that required. On
  8.  *  success, the length of s is returned, -1 otherwise.
  9.  */
  10. ssize_t getln (char **s, size_t *n, FILE *stream)
  11. {
  12. #ifndef SZINIT
  13. #define SZINIT 1024
  14. #endif
  15.     int c = 0;
  16.     size_t maxc = *n ? *n : SZINIT;
  17.     ssize_t nchr = 0;
  18.  
  19.     if (!(*s = realloc (*s, (maxc + 1) * sizeof **s)))
  20.         return -1;
  21.  
  22.     while ((size_t)nchr < maxc && (c = fgetc (stream)) != EOF && c != '\n')
  23.     {
  24.         (*s)[nchr++] = c;   /* assign char to s, increment nchr */
  25.  
  26.         if ((size_t)nchr == maxc)   /* test if limit is reached */
  27.         {
  28.             if (*n) {  /* if reading only *n chars, flush stdin */
  29.                 while ((c = fgetc (stream)) != '\n' && c != EOF);
  30.                 break;
  31.             }
  32.             else {     /* realloc as required, adding SZINIT */
  33.                 void *tmp = realloc (*s, (maxc + SZINIT) * sizeof **s);
  34.                 if (!tmp)
  35.                     return -1;  /* return failure on short read */
  36.                 *s = tmp;
  37.                 maxc += SZINIT;
  38.             }
  39.         }
  40.     }
  41.     (*s)[nchr] = 0; /* nul-terminate */
  42.  
  43.     /* final realloc to trim allocation to exact amount.
  44.      * validate: update s only on success. (optional)
  45.      */
  46.     void *tmp = realloc (*s, (nchr + 1) * sizeof **s);
  47.     if (tmp)
  48.         *s = tmp;
  49.  
  50.     return nchr || c != EOF ? nchr : -1;
  51. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement