-
Reading Input From stdin
Recently I need a way to read a line from stdin, but it was quite important that I read the entire line (as some of the inputs were quite large). So I decided to have a go at writing a function, that reads, character by character input from stdin until it reaches either EOF or '\n'. It would then add the character that it read onto the end of a char array (malloc'ed) which is passed in as the first parameter. My code, however does not work (and even if it did it would have a good few problems), but this was the best that I could come up with:
Code:
int getLine (char *charPtr)
{
char c;
int i;
int totalAlloc = 32;
charPtr = malloc(32);
for (i = 0; (c = fgetc(stdin)) != EOF || c != '\n'; i++)
{
if ((i + 1) > totalAlloc)
{
realloc(charPtr, totalAlloc + 32);
totalAlloc += 32;
}
charPtr[i] = c;
}
i += 2;
realloc(charPtr, i);
charPtr[i - 1] = '\0';
return i;
}
The function assumes that the memory passed to it has been freed first. The idea is to reach each char from stdin and add it onto the end of the array, if the array is out of space then allocate some more. I am not sure why it does not work (compiles fine...) but the only problem that I can see is with realloc. If the memory that it allocates has a different address then I am in trouble, as I (do not think) that I am able to change the memory that the pointer parameter points to (by that I mean assign charPtr to a different memory address).
Can anyone help me?
-
-
Code:
(c = fgetc(stdin)) != EOF || c != '\n'
[edit]
That's always true! for it to be false, c would have to be EOF and '\n' at the same time! :O
[/edit]
-
Code:
int getLine (char *charPtr)
{
char c; /* EOF is an int value; see the FAQ */
int i;
int totalAlloc = 32; /* why 32? */
charPtr = malloc(32);
for (i = 0; (c = fgetc(stdin)) != EOF || c != '\n'; i++)
{
if ((i + 1) > totalAlloc)
{
realloc(charPtr, totalAlloc + 32); /* why 32? */
totalAlloc += 32;
}
charPtr[i] = c;
}
i += 2; /* Why 2? */
realloc(charPtr, i);
charPtr[i - 1] = '\0';
return i;
}
-
I did not use fgets as I do not know how much they will type. It could be up to (and if redirecting stdin) over 10k.
I used the number 32 because, well, it seemed like a reasonable number to increment the size by, (I will #define it at some point when I get it all working).
I add +=2 to i, because i has the number of chars they typed in -1 (arrays start at 0), now I need enough space for a '\0', so I need to allocate it to the size of i + 2 .
I will try changing || (OR) to && (AND).
-
> realloc(charPtr, totalAlloc + 32);
Try assigning the result somewhere.
Better yet, check that realloc actually worked.
Code:
void *temp = realloc(charPtr, totalAlloc + 32);
if ( temp != NULL ) {
charPtr = temp;
} else {
/* failed - carry on doing something with charPtr */
/* this should include free(charPtr) at some point */
}