char* str = NULL;
size_t capacity = 0;
getline(&str, &capacity, stdin);
The above code is an example of using getline to dynamically allocate memory while reading a string input. But, what if I'm trying to read the input into a 2D array?
Example:
Linenumberone (enter)
Linenumbertwo (enter)
(enter) <<< enter on an empty line - stop reading user input
I do know about the function strlen, so I was thinking I could technically use that to figure out when to stop reading user input? But I'm a bit confused, is it even possible to read user input using getline into a 2D array in C as described? I've only seen people using it in C++
We can declare an array of pointers, then assign each line to the 2D array in a loop. See the code below:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *line[5] = {NULL}; // array of 5 pointers
size_t len = 0;
int i=0;
for(i=0;i<5;i++)
{
getline(&line[i],&len, stdin); // reading strings
}
printf("\nThe strings are \n");
for(int i=0; i<5; i++)
{
printf("%s",line[i]); // prinitng the strings.
}
return 0;
}
The output is (first 5 lines are input) :
krishna
rachita
teja
sindhu
sagarika
The strings are
krishna
rachita
teja
sindhu
sagarika
Each time characters = getline(&str,...) is used, new dynamic memory is allocated at the address str, with a size equal to number of characters read. It suffices to store the buffer address (value of str) into an array at each getline() call. Subsequently, the buffer address (str) in getline() is incremented by the number of characters read in the last getine(). See code and example below.
#include <stdio.h>
int main () {
char *buffer=NULL;
size_t capacity = 0;
size_t maxlines = 100;
char *lines[maxlines]; // pointers into the malloc buffer for each line
printf ("Input\n\n");
int lines_read;
int characters;
// read getline until empty line or maxlines
for (lines_read = 0; lines_read < maxlines; lines_read++) {
printf ("Enter line %d: ", lines_read + 1);
characters = getline (&buffer, &capacity, stdin);
// stop at empty line
if (characters == 1) break;
// convert end of line "\n" into zero (C null-terminated string convention)
buffer[characters - 1] = 0;
// save starting location into lines
lines[lines_read] = buffer; // save pointer to the start of this line in the buffer
buffer += characters; // set pointer to the start of a new line in the buffer
}
printf ("\nOutput\n\n");
// print lines read excluding empty line
for (int i = 0; i < lines_read; i++)
printf ("Line[%d] = %s\n", i+1, lines[i]);
return (0);
}
Example output:
Input
Enter line 1: This
Enter line 2: is
Enter line 3: an
Enter line 4: example.
Enter line 5:
Output
Line[1] = This
Line[2] = is
Line[3] = an
Line[4] = example.
Related
I'm writing a c code to read strings from stdin with scanf() and while loop (into a two-dimensional char array). My strategy is to use an input array to temporarily store each string and then assign it to a preword array (fixed sized). However, my strategy failed and all strings stored in my arrays are the same (the last string input). How to fix it?
I used a fgets() and it works find. However, I cannot use it to deal with a new line of strings (from stdin). My fgets() reads only the first line and that's why I turn to scanf and while loop.
#include<stdio.h>
#include<stdlib.h>
#define MAX 1000
#define size 50
int main ()
{
int count = 0;
char input[size];
char * preword[MAX];
while (scanf("%s",input)!= EOF){
preword[count] = input;
printf("preword[%d] is %s\n",count,preword[count]);
count++;
}
printf("the count is %d\n",count);
for (int i = 0; i < count; i++){
printf("preword[%d] is %s\n",i,preword[i]);
}
return 0;
}
I expect my input arrays from stdin will be stored in a two-dimensional char array. Below is the output in terminal after compilation. My input is a txt file, in which I have
hello world
I am a hero
It turns out that all strings stored in the two-d array are the last word.
preword[0] is hello
preword[1] is world
preword[2] is I
preword[3] is am
preword[4] is a
preword[5] is hero
the count is 6
preword[0] is hero
preword[1] is hero
preword[2] is hero
preword[3] is hero
preword[4] is hero
preword[5] is hero
Firstly here
char * preword[MAX];
preword is array of character pointer i.e each element is a char pointer & when you are doing like
preword[count] = input;
as #paddy pointed its copies input in every element of preword and it's the same pointer since you haven't allocated memory for preword[count], correct way is to allocate memory for each pointer and then copy.
Also use fgets() instead of scanf() here. For e.g
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 1000
#define size 50
int main (void)
{
int count = 0;
char input[size] = {0};
char * preword[MAX] = {0};
size_t retStrCspn = 0;
while (fgets(input, size, stdin) != NULL){
/* remove trailing new line if its stored at end of buffer by fgets() */
input[retStrCspn = strcspn(input, "\n")] = 0; /* remove the trailing & use the return value for allocating memory purpose \n */
preword[count] = malloc(retStrCspn + 1); /* Allocate memory for each pointer elements */
if(preword[count] != NULL) {
memcpy (preword[count], input, retStrCspn + 1); /* copy input buffer into each different memory location */
printf("preword[%d] is %s\n",count,preword[count]);
count++;
}
else {
/* #TODO malloc erro handling */
}
}
printf("the count is %d\n",count);
for (int i = 0; i < count && preword[i] != NULL; i++){
printf("preword[%d] is %s\n",i,preword[i]);
free(preword[count]); /* free dynamically allocated memory here*/
}
return 0;
}
I tried to get the inputs(strings) from user and store them in an array.But after I ran this code, the program instantly crashed.
#include <stdio.h>
int main() {
int i;
char *word[3];
for(i=0;i<3;i++)
{
printf(" Enter a word: ");
scanf("%s", &word[i]);
}
printf("%s ", word[0]);
return 0;
}
In this line:
scanf("%s", &word[i]);
You need to make sure word[i] is pointing somewhere, and has enough space to occupy the string entered. Since word[i] is a char * pointer, you need to at some time allocate memory for this. Otherwise, it is just a dangling pointer not pointing anywhere.
If you want to stick with scanf(), then you can allocate some space beforehand with malloc.
malloc() allocates requested memory on the heap, then returns a void* pointer at the end.
You can apply malloc() in your code like this:
size_t malloc_size = 100;
for (i = 0; i < 3; i++) {
word[i] = malloc(malloc_size * sizeof(char)); /* allocates 100 bytes */
printf("Enter word: ");
scanf("%99s", word[i]); /* Use %99s to avoid overflow */
/* No need to include & address, since word[i] is already a char* pointer */
}
Note: Must check return value of malloc(), because it can return NULL when unsuccessful.
Additionally, whenever you allocate memory with the use of malloc(), you must use free to deallocate requested memory at the end:
free(word[i]);
word[i] = NULL; /* safe to make sure pointer is no longer pointing anywhere */
Another approach without scanf
A more proper way to read strings should be with fgets.
char *fgets(char *str, int n, FILE *stream) reads a line from an input stream, and copies the bytes over to char *str, which must be given a size of n bytes as a threshold of space it can occupy.
Things to note about fgets:
Appends \n character at the end of buffer. Can be removed easily.
On error, returns NULL. If no characters are read, still returns NULL at the end.
Buffer must be statically declared with a given size n.
Reads specified stream. Either from stdin or FILE *.
Here is an example of how it can be used to read a line of input from stdin:
char buffer[100]; /* statically declared buffer */
printf("Enter a string: ");
fgets(buffer, 100, stdin); /* read line of input into buffer. Needs error checking */
Example code with comments:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUMSTR 3
#define BUFFSIZE 100
int main(void) {
char *words[NUMSTR];
char buffer[BUFFSIZE];
size_t i, count = 0, slen; /* can replace size_t with int if you prefer */
/* loops only for three input strings */
for (i = 0; i < NUMSTR; i++) {
/* read input of one string, with error checking */
printf("Enter a word: ");
if (fgets(buffer, BUFFSIZE, stdin) == NULL) {
fprintf(stderr, "Error reading string into buffer.\n");
exit(EXIT_FAILURE);
}
/* removing newline from buffer, along with checking for overflow from buffer */
slen = strlen(buffer);
if (slen > 0) {
if (buffer[slen-1] == '\n') {
buffer[slen-1] = '\0';
} else {
printf("Exceeded buffer length of %d.\n", BUFFSIZE);
exit(EXIT_FAILURE);
}
}
/* checking if nothing was entered */
if (!*buffer) {
printf("No string entered.\n");
exit(EXIT_FAILURE);
}
/* allocate space for `words[i]` and null terminator */
words[count] = malloc(strlen(buffer)+1);
/* checking return of malloc, very good to do this */
if (!words[count]) {
printf("Cannot allocate memory for string.\n");
exit(EXIT_FAILURE);
}
/* if everything is fine, copy over into your array of pointers */
strcpy(words[count], buffer);
/* increment count, ready for next space in array */
count++;
}
/* reading input is finished, now time to print and free the strings */
printf("\nYour strings:\n");
for (i = 0; i < count; i++) {
printf("words[%zu] = %s\n", i, words[i]);
free(words[i]);
words[i] = NULL;
}
return 0;
}
Example input:
Enter a word: Hello
Enter a word: World
Enter a word: Woohoo
Output:
Your strings:
words[0] = Hello
words[1] = World
words[2] = Woohoo
There seems to be a bit of confusion in this area. Your primary problem is you are attempting to write each word to the address of each of pointers you declare with char *word[3];. (not to mention you have no storage allocated at the location pointed to by each pointer -- but you never get there as you attempt to write to the address of each pointer with &word[i] rather than to the pointer itself)
While you can use scanf you will quickly run into one of the many pitfalls with taking user input with scanf that plague all new C programmers (e.g. failing to handle the '\n' left in the input buffer, failing to handle whitespace in strings, failing to limit the number of characters read/written, failing to validate the read or handle EOF, etc...)
A better approach is to simply use fgets and then trim the '\n' that fgets read and includes in the buffer to which it stores the string. A simple example would be:
#include <stdio.h>
#include <string.h>
#define NWDS 3 /* declare a constant for the maximum number of words */
int main (void) {
int i, n = 0;
char word[NWDS][50] = { "" }; /* provide storage or allocate */
for (i = 0; i < NWDS; i++) { /* for a max of NWDS */
printf ("Enter word : "); /* prompt */
if (!fgets (word[i], sizeof word[i], stdin)) /* read/validate */
break; /* protect against EOF */
size_t len = strlen (word[i]); /* get length */
if (word[i][len-1] == '\n') /* check for trailing '\n' */
word[i][--len] = 0; /* overwrite with nulbyte */
}
n = i; /* store number of words read */
putchar ('\n'); /* make it pretty */
for (i = 0; i < n; i++) /* output each word read */
printf (" word[%d] : %s\n", i, word[i]);
#if (defined _WIN32 || defined _WIN64)
getchar(); /* keep terminal open until keypress if on windows */
#endif
return 0;
}
Go ahead and cancel input at any time by generating an EOF during input (ctrl + d on Linux or ctrl + z on windoze), you are covered.
Example Use/Output
$ ./bin/wordsread
Enter word : first word
Enter word : next word
Enter word : last word
word[0] : first word
word[1] : next word
word[2] : last word
Looks things over, consider the other answers, and let me know if you have further questions.
char *word[3]; // <-- this is an array of 3 dangling pointers, of type char*
// they still point nowhere, we later need to set them to some allocated location.
...
for(i=0;i<3;i++) {
word[i] = malloc(some_max_size * sizeof(char)); // <-- allocate space for your word
printf(" Enter a word: ");
scanf("%s", word[i]); // <-- not &word[i]; word[i] is already a char* pointer
}
You are declaring word as array of pointer (char *word[3];). You have to allocate memory to store data. Allocate memory with malloc or similar functions before assigning values.
Yes the code crashes because declaring an array of character
pointers is not enough, you need to set the pointers to point
to memory where the strings can be stored.
E.g.
const int maxLen = 32;
char* word[3] = {NULL,NULL,NULL};
word[i] = malloc(maxLen);
then read the string from keyboard, to ensure that the string is not too
long use fgets and maxLen:
printf("Enter a word:");
fgets(word[i],maxLen,stdin);
#include <stdio.h>
int main(){
int n;
int i=0;
scanf("%d",&n);
char arr[n];
while(n>i){
scanf("%s",&arr[i]);
i+=1;
}
while(n-i<n){
printf(" %c ",arr[n-i]);
i-=1;
}
}
The code char *word[3] made a 3-element array of pointers!
See, you have basically created a character array of pointers, so you cannot put a "string" into each one of them, because the type of a pointer variable is long hexadecimal.
#include <stdio.h>
#include <stdlib.h>
void *salloc(int x){
char **pointer;
int i;
pointer = malloc(sizeof(char)*x);
if(pointer == NULL){
exit(-1);
}
for(i=0; i<x; i++){
pointer[i] = malloc(sizeof(char) * 20);
if(pointer[i] == NULL){
exit(-1);
}
}
return pointer;
}
void Input(int value, char **array){
for(i = 0; i < value; i++){
printf("%d ----\n", i);
fgets(array[i], 20, stdin);
printf("%d ----\n", i);
}
}
int main(int argc, char *argv[]){
char **array;
int value = 2;
array = salloc(value);
Input(value, array);
return 0;
}
The general idea, can be that I miss some syntax.
So I want to read in a string with spaces. If I run this for the value 2, it will print:
0 ----
0 ----
1 ----
"some string"
and it crashes after I press enter.
If I do this with value 1:
it immediately crashes.
However if I replace fgets() with:
scanf("%s", array[i]);
it works (except for the spaces).
So how does fgets() work in 2d-arrays?
Because I get it to work in 1d-arrays. And for some reason I can print 1d-arrays from row 2 when the array only has 2 rows, so it should only be able to print from rows 0 and 1 right?
Here is a demonstrative program that shows how fgets can be used with a 2D array.
#include <stdio.h>
#define N 5
#define M 10
int main( void )
{
char lines[N][M];
size_t n = 0;
while( n < N && fgets( lines[n], sizeof( *lines ), stdin ) != NULL ) ++n;
for ( size_t i = 0; i < n; i++ ) puts( lines[i] );
return 0;
}
If to enter for example
One
Two
Three
Four
Five
then the program output will be the same
One
Two
Three
Four
Five
When you do
pointer = malloc(sizeof(char)*x);
you only allocate x characters (i.e. bytes), not pointers to characters. Change to
pointer = malloc(sizeof(char*)*x);
Without the change, you might go out of bounds and have undefined behavior. And this is exactly what happens in your code, you allocate only two bytes to store two pointers, and a single pointer is either four or eight bytes, so you don't allocate enough memory for even a single pointer.
Undefined behavior is a common cause of crashes, but sometimes it might also seem to work.
Note also when taking input with fgets (or any of the line-oriented input functions), fgets will read up to, and include, the '\n' at the end of each line read. You should perform 2 additional tests/operations. (1) you should test that the last character read by fgets is in fact the '\n' character. If it is not, that will indicate your input was truncated by fgets at the length you specified in the second parameter to fgets, and additional character remain unread for that line. Without this check and some way to handle lines that exceed the specified width, you next call to fgets will read the remaining characters for the current line as your next line of input.
(2) you should remove the newline included by fgets to prevent your strings from containing embedded '\n' characters at the end. (if you are simply parsing numbers from the line and not storing it as a string, this can be handled in several different manners). But, for the general case, you use strlen to locate the end of the string, and then overwrite the '\n' with a nul-terminating character.
In addition to the above, it may make more sense to allocate memory for each individual pointer in array only after a line of data has been read to prevent over-allocating space in your code. Since you are specifying that the allocation size for each string will be 20, a simple character buffer of that size can be used to take input, and after confirming input, you can allocate storage for that line in array. A short example of your function with the checks included and with allocation included in input would be:
#define MAXC 20 /* max chars per read */
...
void Input (int value, char **array)
{
int i = 0;
size_t len = 0;
char buf[MAXC] = {0};
while (i < value && fgets (buf, MAXC, stdin)) {
printf ("%d ----\n", i);
len = strlen (buf); /* get length */
if (len + 1 == MAXC && buf[len-1] != '\n') /* validate read */
fprintf (stderr, "warning: chars exceed MAXC, line[%d]\n", i);
else
buf[--len] = 0; /* strip '\n' */
printf ("%d ----\n", i);
array[i++] = strdup (buf); /* allocate/copy */
}
}
Lastly, why choose void as the function type? Why not return the number of values read into array if values are successfully read into array, or 0 otherwise. This will at least allow some indication of success or failure of your read and provide a way of returning the number of lines allocated back to the calling function.
An example of your code incorporating the adjusted allocation, necessary checks, and useful return types would be:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXC 20
void *salloc (int x)
{
char **pointer;
pointer = malloc (sizeof *pointer * x);
if (pointer == NULL)
exit(-1);
return pointer;
}
int input (int value, char **array)
{
int i = 0;
size_t len = 0;
char buf[MAXC] = {0};
while (i < value && fgets (buf, MAXC, stdin)) {
printf ("%d ----\n", i);
len = strlen (buf); /* get length */
if (len + 1 == MAXC && buf[len-1] != '\n') /* validate read */
fprintf (stderr, "warning: chars exceed MAXC, line[%d]\n", i);
else
buf[--len] = 0; /* strip '\n' */
printf ("%d ----\n", i);
array[i++] = strdup (buf); /* allocate/copy */
}
return i;
}
int main (int argc, char *argv[]) {
int i, nlines, value = argc > 1 ? atoi (argv[1]) : 2;
char **array;
array = salloc (value);
if (!(nlines = input (value, array))) /* validate input */
return 1;
for (i = 0; i < nlines; i++) /* print input */
printf (" array[%2d] : %s\n", i, array[i]);
for (i = 0; i < nlines; i++) /* free memory */
free (array[i]);
free (array);
return 0;
}
Test Input File
The following is a test input file where line 1 (the 2nd line) exceedS 20 characters:
$ cat dat/captnjack.txt
This is a tale
Of Captain Jack Sparrow
A Pirate So Brave
On the Seven Seas.
Example Output
$ ./bin/readarray 10 <../dat/captnjack.txt
0 ----
0 ----
1 ----
warning: chars exceed MAXC, line[1]
1 ----
2 ----
2 ----
3 ----
3 ----
array[ 0] : This is a tale
array[ 1] : Of Captain Jack Spa
array[ 2] : rrow
array[ 3] : A Pirate So Brave
array[ 4] : On the Seven Seas.
Don't forget to use a memory error check program like valgrind to validate your use of the memory you allocate and to insure you have freed it when it is no longer needed. Let me know if you have any additional questions.
I have a text file with names that looks as follows:
"MARY","PATRICIA","LINDA","BARBARA","ELIZABETH","JENNIFER","MARIA","SUSAN","MARGARET",
I have used the following code to attempt to put the names into an array:
char * names[9];
int i = 0;
FILE * fp = fopen("names.txt", "r");
for (i=0; i < 9; i++) {
fscanf(fp, "\"%s\",", names[i]);
}
The program comes up with a segmentation fault when I try to run it. I have debugged carefully, and I notice that the fault comes when I try and read in the second name.
Does anybody know why my code isn't working, and also why the segmentation fault is happening?
You have undefined behavior in your code, because you don't allocate memory for the pointers you write to in the fscanf call.
You have an array of nine uninitialized pointers, and as they are part of a local variable they have an indeterminate value, i.e. they will point to seemingly random locations. Writing to random locations in memory (which is what will happen when you call fscanf) will do bad things.
The simplest way to solve the problem is to use an array of arrays, like e.g.
char names[9][20];
This will gives you an array of nine arrays, each sub-array being 20 characters (which allows you to have names up to 19 characters long).
To not write out of bounds, you should also modify your call so that you don't read to many characters:
fscanf(fp, "\"%19s\",", names[i]);
There is however another problem with your use of the fscanf function, and that is that the format to read a string, "%s", reads until it finds a whitespace in the input (or until the limit is reached, if a field width is provided).
In short: You can't use fscanf to read your input.
Instead I suggest you read the whole line into memory at once, using fgets, and then split the string on the comma using e.g. strtok.
One way of handling arbitrarily long lines as input from a file (pseudoish-code):
#define SIZE 256
size_t current_size = SIZE;
char *buffer = malloc(current_size);
buffer[0] = '\0'; // Terminator at first character, makes the string empty
for (;;)
{
// Read into temporary buffer
char temp[SIZE];
fgets(temp, sizeof(temp), file_pointer);
// Append to actual buffer
strcat(buffer, temp);
// If last character is a newline (which `fgets` always append
// if it reaches the end of the line) then the whole line have
// been read and we are done
if (last_character_is_newline(buffer))
break;
// Still more data to read from the line
// Allocate a larger buffer
current_size += SIZE;
buffer = realloc(buffer, current_size);
// Continues the loop to try and read the next part of the line
}
// After the loop the pointer `buffer` points to memory containing the whole line
[Note: The above code snippet doesn't contain any error handling.]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char *names[9], buff[32];
int i = 0;
FILE *fp = fopen("names.txt", "r");
for(i = 0; i < 9; i++) {
if(1==fscanf(fp, "\"%31[^\"]\",", buff)){//"\"%s\"," does not work like that what you want
size_t len = strlen(buff) + 1;
names[i] = malloc(len);//Space is required to load the strings of each
memcpy(names[i], buff, len);
}
}
fclose(fp);
//check print & deallocate
for(i = 0; i< 9; ++i){
puts(names[i]);
free(names[i]);
}
return 0;
}
try this...
for (i=0; i < 9; i++)
{
names[i]=malloc(15);// you should take care about size
fscanf(fp, "\"%s\",", names[i]);
}
This is a problem I don't understand - I am using fgets() in main and it works. I use it (I think) in exactly the same way in a function and I get an error [Segmentation fault core dumped -- exit code 139).
This code is based on a sample program in book Ivor Horton's "Beginning C" (it's a old tile but I'm just wanting to learn the basics from it).
My program is as follows. I am working on *nix using Geany (basically, compiling with GCC). You can see that fgets works in main (output is the string you enter). But it doesn't work in the function str_in(). It gets as far as the second printf() statement to enter a string, no further. Note that in the book, Horton uses gets(). I am trying to implement a safer string input function here, but no joy.
By the way the program is supposed to sort strings stored in an array of string pointers.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
#define MAX_NUM_STRINGS 50
int str_in(char **); /*Pointer to a string pointer*/
void str_sort(char *[], int n); /*Array of pointers to strings, number of strings in array*/
void str_out (char *[], int n); /*Array of pointers to strings, number of strings in array*/
int main(){
char *pS[MAX_NUM_STRINGS] = { NULL }; /*Array of pointers to strings stored in str_space*/
int numStrings = 0; /*Count of strings*/
char buffer[BUFSIZ];
printf("Enter a string\n");
fgets(buffer, BUFSIZ, stdin);
printf("%s", buffer);
printf("fgets works here\n\n");
/* get string input from user - a pointer to each string is saved in pS */
while ( str_in(&pS[numStrings]) && numStrings < MAX_NUM_STRINGS)
numStrings++;
if ( numStrings > 0 ){
str_sort(pS, numStrings);
str_out(pS, numStrings);
}
return 0;
}
int str_in(char** pString){
char buffer[BUFSIZ];
char *p;
printf ("Enter string:\n");
fgets(buffer, 60, stdin);
printf("fgets doesn't work here!!\n");
if( buffer != NULL ){
printf("here");
if ((p = strchr(buffer, '\n')) != NULL)
*p = '\0'; /*replace newline with null character*/
else
return FALSE;
if ( strlen(buffer) > 0 ){
strcpy(*pString, buffer);
return TRUE;
}
else
return FALSE; /*blank line - end of input*/
}
else
return FALSE;
}
void str_sort(char* pStrings[], int n){
/*sort strings by manipulating array of string pointers*/
char *temp;
int sorted = FALSE;
int i = 0;
while (!sorted){
sorted = TRUE;
for(i = 0; i < n - 1; i++){
temp = pStrings[i];
if ( strcmp(temp, pStrings[i+1]) > 1 ){
pStrings[i] = pStrings[i+1];
pStrings[i+1] = temp;
sorted = FALSE;
break;
}
}
}
}
void str_out(char* pStrings[], int n){
/*print strings to standard output. Free memory as each string is printed */
int i = 0;
printf("Sorted strings:\n");
for(i = 0; i < n; i++){
printf("%s", pStrings[i]);
free(pStrings[i]);
}
}
The segmentation fault is not caused by fgets(), but by strcpy():
strcpy(*pString, buffer);
You try to write to *pString, but you never allocate memory for it. pS in main() is just an array of null pointers.
Another thing is with the test with if( buffer != NULL ), that would never be true since buffer is an array, not a pointer.
You must check for the return value of fgets to see if you have successfully received something, if not then you should never use your buffer as a string as you are not NUL terminating the buffer.
/* Checking for buffer != NULL is of no use */
/* as buffer will always be not NULL since */
/* since you have allocated it as char buffer[BUFSIZ] */
if (fgets(buffer, BUFSIZ, stdin) == NULL) {
/* buffer may not be a valid string */
}
So what you can do it to initialize the buffer to a NUL string, as soon as you enter the function (after your declarations are done
buffer[0] = 0; /* initialize to NUL string */
now you can use buffer as a string anywhere.
Also note than if BUFSIZ is too big greater than a couple of KB, then your might get seg fault due to stack overflow. If they are too big you could make buffer as "static char" instead of "char".