#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#pragma warning(disable: 4996)
/* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR
(and null-terminate it). *LINEPTR is a pointer returned from malloc (or
NULL), pointing to *N characters of space. It is realloc'd as
necessary. Returns the number of characters read (not including the
null terminator), or -1 on error or EOF. */
static __inline void __set_errno(unsigned int no)
{
errno = no;
}
size_t __getdelim (char** lineptr, size_t* n, int terminator,FILE* stream)
{
const size_t BLOCKSIZE = 255;
int c;
size_t len = 0;
size_t linesize = 0;
int newalloc = 0;
if( lineptr == NULL || stream == NULL || n == NULL)
{
_set_errno(EINVAL);
return -1;
}
linesize = BLOCKSIZE;
if( *lineptr == NULL)
{
// allocate new memory if required
*lineptr = malloc(BLOCKSIZE);
*n = BLOCKSIZE;
newalloc = 1;
}
else
linesize = *n;
while( (c = fgetc(stream)) != EOF && c != terminator)
{
// make sure we have enough room for the new character
// If not, then streatch it out a bit.
if( (len+1) == linesize)
{
linesize += BLOCKSIZE;
*n = linesize;
*lineptr = realloc(*lineptr, linesize);
}
(*lineptr)[len++] = c;
}
if( len == 0 && c != terminator) // check for blank lines
{
_set_errno(EINVAL);
if( newalloc )
{
free(*lineptr);
*lineptr = NULL;
}
else
(*lineptr)[0] = 0; // truncate the string
return -1;
}
(*lineptr)[len] = 0; // null-terminate the string
return len;
}
int main()
{
unsigned int n = 255;
char* lineptr = malloc(n);
FILE* fp = fopen("test3.c", "r");
if( fp != NULL)
{
while(__getdelim(&lineptr, &n, '\n', fp) != -1 )
{
printf("%s\n", lineptr);
}
free(lineptr);
lineptr = NULL;
fclose(fp);
}
}