fscanf in C with a text file with no spaces - c

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]);
}

Related

C / Getting line string from text file and storing them in array/pointer

I want to get all lines from the text file and store them in my char** pointer (array of strings). The problem is that when I try to set indices for pointer's strings, the program assigns the last scanned sentence for all indices.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE 10000
int main()
{
FILE *fp = NULL;
char line[MAX_LINE];
char** lines = (char**) malloc(10000*200*sizeof(char));
int count = 0;
fp = fopen("test.txt","r");
while(fgets(line,10000,fp)) {
lines[count] = line;
count++;
}
fclose(fp);
for(int i =0; i<2000;i++){
printf("%s",lines[i]);
}
return 0;
}
lets assume test.txt is like this:
Alice was beginning to get very tired of sitting by her sister on the
bank, and of having nothing to do: once or twice she had peeped into the
book her sister was reading, but it had no pictures or conversations in
it, and what is the use of a book, thought Alice without pictures or
conversations?
When I print like this, every time I get the last sentence (in this case conversations? ) in my text file. However, I want to set every scanned sentence from the text file to the different index in my char**. For example, I want to set like this:
lines[0] gives "Alice was beginning to get very tired of sitting by her sister on the"
lines[1] gives "bank, and of having nothing to do: once or twice she had peeped into the"
and so on.
You can't copy characters from one string buffer to another simply by assigning a pointer (all that does is to make the destination point to the source, as you have noticed).
Instead, you must actually copy the characters, using the strcpy function. So, instead of:
lines[count] = line; // Just makes each pointer point to the same buffer
use:
strcpy(lines[count], line); // Copies the CURRENT contents of "line"
You also have a severe problem in the way you are using your char** lines buffer. If you want an array of 200 lines, each with a maximum length of 10000 characters, you should allocate them as follows:
char** lines = malloc(200 * sizeof(char*)); // Make 200 pointers
// Now allocate 10000 chars to each of these pointers:
for (int i = 0; i < 200; ++i) lines[i] = malloc(10000 * sizeof(char));
Note: The 200 buffers will be uninitialized (contain random data) so, in your print loop, you should only use those you have copied real data to, using the count variable as the loop limit:
for(int i = 0; i < count; i++) {
printf("%s", lines[i]);
}
Also, don't forget to free the memory allocated when you're done:
for (int i = 0; i < 200; ++i) free(lines[i]); // Free each line buffer...
free(lines); // ... then free the array of pointers itself
strdup resolve the issue, free resources as said by Adrian when finished.
int main()
{
FILE *fp = NULL;
char line[MAX_LINE];
char** lines = (char**) malloc(10000*200*sizeof(char));
int count = 0;
fp = fopen("test.txt","r");
while(fgets(line,10000,fp)) {
lines[count] = strdup(line);
count++;
}
fclose(fp);
for(int i =0; i<count;i++){
printf("%s",lines[i]);
}
for (int i = 0; i < count; ++i) free(lines[i]);
free(lines);
return 0;
}
If you are looking for better performance look at my repo (https://github.com/PatrizioColomba/strvect)

C/ String data from file to array. Segmentation Fault

I am writing a program that streams words from a text file and puts them into an array. I've also added a display of array data to see if everything is ok but I get a segmentation fault after compiling.
I am new to system programming so I am aware I might have done some basic mistakes. Please find the code below and tell me where have I gone wrong.
#include <stdio.h>
#define BUFFER 100
int main() {
char tab[BUFFER];
FILE *wp;
wp = fopen("tab_file_b_words.txt", "r");
if(wp == NULL)
{
printf("error/n");
return -1;
}
int i;
for(i=0; i<sizeof(wp); i++) {
if(wp != NULL)
fscanf(wp, "%s", &tab[i]);
else
break;
}
printf("Content: \n");
for(i = 0; i < BUFFER; i++) {
if(tab[i] != NULL)
printf("%s\n", tab[i]);
else
break;
}
fclose(wp);
return 0;
}
As of now you are having array of char
what you need is
char tab[BUFFER]; --> char tab[BUFFER][SOME_LENGTH];
And
fscanf(wp, "%s", &tab[i]); --> fscanf(wp, "%s", tab[i]);
%s expects null terminated char * but you are passing char.
printf("%s\n", tab[i]);
sizeof(wp) is size of pointer.
for(i=0; i<sizeof(wp); i++)
What you need is
while (1 == fscanf(wp, "%s", tab[i]))
{
...
}
This section:
for(i=0; i<sizeof(wp); i++) {
if(wp != NULL)
fscanf(wp, "%s", &tab[i]);
else
break;
}
Is problematic.
First, there are a couple of issues with the line: fscanf(wp, "%s", &tab[i]); It should be written as:
fscanf(wp, "%s", tab); //removed & and array notation.
Unlike int or float variable types, the name of your char array (i.e. tab) is already a pointer pointing to the address of the variable, making it unnecessary (and incorrect) to use the address of operator (&).
Related to above... (and likely cause of segmentation fault.)
Because the definition of tab is for a simple array of char ( char tab[BUFFER]; ), the notation tab[i] refers only to the ith byte (or char) of the array, not the entire array. Because of the "%s" format specifier used, the function fscanf() expects a char * not a char, making tab the correct argument to use.
If you want to use an array of lines the variable must be created as a 2D array of char:
#define NUM_LINES 100
#define LINE_LEN 80
int main() {
char tab[NUM_LINES][LINE_LEN] = {{0}}; // zero initialized array of
// NUM_LINE strings
// each of LINE_LEN-1 capacity
In the statement for(i=0; i<sizeof(wp); i++) {
sizeof(wp)
will be equal to the number of bytes of the pointer wp, either 32 or 64 depending on the target addressing of your application. This is probably not what you intended. (or want.)
Consider a different approach:
Given you are working with text files, try using a combination of while() and fgets() to read lines from the file. Then you can process each line based on its known syntax.
(Following example uses a single dimension char array for simplified illustration.)
char line[some_len];
wp = fopen(some_file_name, "r");
if(wp)
{
while(fgets(line, some_len, wp))
{
// use line. In this case, just print to stdout
printf("%s\n", line);
}
fclose(wp);
}
sizeof(wp) is the problem.
sizeof returns the length of a type in bytes and not the length of the file.
If you want to get the size of a file this may help you.

C - Saving strings into array elements

I have a notepad file with approximately 150,000 words (representing a dictionary). I'm trying to scan in each word and print it to the console. This setup works fine:
void readDictionary(FILE *ifp, int numWords) {
fscanf(ifp, "%d", &numWords);
printf("%d\n", numWords);
int i;
char* words = (char*)malloc(20 * sizeof(char));
for(i = 0; i < numWords; i++) {
fscanf(ifp, "%s", words);
printf("%s\n", words);
}
}
However, this code obviously overwrites "words" each time it loops. I'm trying to get each word to save to a certain array element. I did the following but it instantly crashes (I changed the memory allocation to 2D because I read around here and it seems that is what I am supposed to do):
void readDictionary(FILE *ifp, int numWords) {
fscanf(ifp, "%d", &numWords);
printf("%d\n", numWords);
int i;
char** words = (char**)malloc(20 * sizeof(char*));
for(i = 0; i < numWords; i++) {
fscanf(ifp, "%s", words[i]);
printf("%s\n", words[i]);
}
}
Any help is appreciated. I've read around on many posts but haven't figured it out.
In your second version, you allocate space for 20 pointers, but you leave those pointers uninitialized and without anything to point to. I'm sure you can imagine how that presents a problem when you then try to read from your dictionary into the memory designated by one of those pointers.
It looks like you want to allocate space for numwords pointers
char** words = malloc(numwords * sizeof(*words));
, and for each of them, to allocate space for a word.
for(i = 0; i < numWords; i++) {
words[i] = malloc(20); // by definition, sizeof(char) == 1
// ...
Additionally, do check the return value of malloc(), which will be NULL in the event of allocation failure.
The first problem is you only allocated space for a list of words (ie. character pointers) but you didn't allocate space for the words themselves.
char** words = (char**)malloc(20 * sizeof(char*));
This allocates space for 20 character pointers and assigns it to words. Now words[i] has space for a character pointer but not for the characters.
words[i] contains garbage, because malloc does not initialize memory. When you pass it into fscanf, fscanf tries to use the garbage in words[i] as a memory location to write characters to. That's either going to corrupt some memory in the program, or more likely it tries to read a memory location is isn't allowed to and crashes. Either way, it's not good.
You have to allocate memory for the string, pass that to fscanf, and finally put that string into words[i].
char** words = malloc(numWords * sizeof(char*));
for(i = 0; i < numWords; i++) {
char *word = malloc(40 * sizeof(char));
fscanf(ifp, "%39s", word);
words[i] = word;
printf("%s\n", words[i]);
}
Note that I didn't cast the result of malloc, that's generally considered unnecessary.
Also note that I allocated space for numWords in the list. Your original only allocates space for 20 words, once it goes over that it'll start overwriting allocated memory and probably crash. As a rule of thumb, avoid constant memory allocations. Get used to dynamic memory allocation as quickly as you can.
Also note that I limited how many characters fscanf is allowed to read to the size of my buffer (minus one because of the null byte at the end of strings). Otherwise if your word list contained "Pneumonoultramicroscopicsilicovolcanoconiosis", 45 characters, it would overrun the word buffer and start scribbling on adjacent elements and that would be bad.
This leads to a new problem that are common to fscanf and scanf: partial reads. When the code above encounters "Pneumonoultramicroscopicsilicovolcanoconiosis" fscanf(ifp, "%39s", word); will read in the first 39 characters, "Pneumonoultramicroscopicsilicovolcanoco" and stop. The next call to fscanf will read "niosis". You'll store and print them as if they were two words. That's no good.
You could solve this by making the word buffer bigger, but now most words will be wasting a lot of memory.
scanf and fscanf have a whole lot of problems and are best avoided. Instead, it's best to read entire lines and parse them with sscanf. In this case you don't need to do any parsing, they're just strings, so getting the line will suffice.
fgets is the usual way to read a line, but that also requires that you try and guess how much memory you'll need to read in the line. To mitigate that, have a large line buffer, and copy the words out of it.
void strip_newline( char* string ) {
size_t len = strlen(string);
if( string[len-1] == '\n' ) {
string[len-1] = '\0';
}
}
...
int i;
/* The word list */
char** words = malloc(numWords * sizeof(char*));
/* The line buffer */
char *line = malloc(1024 * sizeof(char*));
for(i = 0; i < numWords; i++) {
/* Read into the line buffer */
fgets(line, 1024, ifp);
/* Strip the newline off, fgets() doesn't do that */
strip_newline(line);
/* Copy the line into words */
words[i] = strdup(line);
printf("%s\n", words[i]);
}
strdup won't copy all 1024 bytes, just enough for the word. This will result in using only the memory you need.
Making assumptions about files, like that they'll have a certain number of lines, is a recipe for problems. Even if the file says it contains a certain number of lines you should still verify that. Otherwise you'll get bizarre errors as you try to read past the end of the file. In this case, if the file has less than numWords it'll try to read garbage and probably crash. Instead, you should read the file until there's no more lines.
Normally this is done by checking the return value of fgets in a while loop.
int i;
for( i = 0; fgets(line, 1024, ifp) != NULL; i++ ) {
strip_newline(line);
words[i] = strdup(line);
printf("%s\n", words[i]);
}
This brings up a new problem, how do we know how big to make words? You don't. This brings us to growing and reallocating memory. This answer is getting very long, so I'll just sketch it.
char **readDictionary(FILE *ifp) {
/* Allocate a decent initial size for the list */
size_t list_size = 256;
char** words = malloc(list_size * sizeof(char*));
char *line = malloc(1024 * sizeof(char*));
size_t i;
for( i = 0; fgets(line, 1024, ifp) != NULL; i++ ) {
strip_newline(line);
/* If we're about to overflow the list, double its size */
if( i > list_size - 1 ) {
list_size *= 2;
words = realloc( words, list_size * sizeof(char*));
}
words[i] = strdup(line);
}
/* Null terminate the list so readers know when to stop */
words[i] = NULL;
return words;
}
int main() {
FILE *fp = fopen("/usr/share/dict/words", "r");
char **words = readDictionary(fp);
for( int i = 0; words[i] != NULL; i++ ) {
printf("%s\n", words[i]);
}
}
Now the list will start at size 256 and grow as needed. Doubling grows pretty fast without wasting too much memory. My /usr/share/dict/words has 235886 lines in it. That can be stored in 218 or 262144. 256 is 28 so it only requires 10 expensive calls to realloc to grow to the necessary size.
I've changed it to return the list, because there isn't much good in building the list if you're just going to use it immediately. This allows me to demonstrate another technique in working with dynamically sized lists, null termination. The last element in the list is set to NULL so anyone reading the list knows when to stop. This is safer and simpler than trying to pass the length around with the list.
That was a lot, but that's all the basic stuff you need to do when working with files in C. It's good to do it manually, but fortunately there are libraries out there which make doing this sort of thing a lot easier. For example, Gnome Lib provides a lot of basic functionality including arrays of pointers that automatically grow as needed.

Adding lines in a file to an array in C

I am trying to read a file, with a name on each line, like
Jim
Abby
Timothy
and store each name in a spot in an array so that I can later work with each individual name. This is the code that I have, but I do not think the names are stored right, because if I change the order of the names in the file, the actions on the name changes too. The actions depend on the name, not the placement.
FILE *ptr_file; // pointer to file
char name[100];
size_t k=0;
ssize_t read;
char *line = NULL;
while ((read= getline(&line, &k, ptr_file))!=-1)
{
fscanf(ptr_file, "%s", &name);
printf("%s ",name);
}
`I am trying to do something like this with the names
for (i =0; i <length-1; i++)
//for the length of the string add each letter's value up
{
num = num + name [i];
}
but when I switch the name's place in the list, the value of num changes as well.
Maybe something like this. In this code I'm assuming there will be less than 200 names in file. You can change this by change size of "names" array
FILE *ptr_file; // pointer to file
char names[200][100];
size_t k=100;
size_t namesCount = 0;
size_t read;
while ((read= getline(names[namesCount], &k, ptr_file))!=-1) //reading name to names array
{
printf("%s ",names[namesCount++]);//printf just readed name
}
getline() does the memory allocation for you when you pass a NULL pointer.
i have commented the code for explanation.
#include <stdio.h>
#include <stdlib.h>
#define THRESHOLD (5)
int main(int argc,char** argv) {
// the file containing the names (one in each line)
char* fn = "test";
// lets open the file (you should check the result!)
FILE* file = fopen(fn,"r");
// allocate memory for the array
char** names = (char**)malloc(THRESHOLD * sizeof(char*));
size_t i;
// set all the values to NULL
for(i=0; i<THRESHOLD; i++) {
names[i] = NULL;
}
// initialize the count
size_t count = 0;
// read all names until EOF and resize the array if needed
while(getline(&names[count],&i,file) != EOF) {
count++;
if(count >= THRESHOLD) {
names = (char**)realloc(names,(count+THRESHOLD)*sizeof(char*));
}
}
// resize (shrink) the array to the actual size
names = (char**)realloc(names,count * sizeof(char*));
// do something with the names (i just print them)
for(i=0; i<count; i++) {
printf("element %d, value %s",i,names[i]);
}
// you have to free the memory (allocated by getline)
for(i=0; i<count; i++) {
free(names[i]);
}
// you have to free memory (allocated by you)
free(names);
return 0;
}
It's difficult to see what you mean, but it looks like there are two fundamental logical problem you have (ignoring the specific technical points highlighted in the other answers).
1) The code reads one line using getline and discarding the result in line, then immediately reading more text from the file using fscanf.
2) Each name read from the file by the fscanf overwrites the name buffer, which is a single string of up to 99 characters plus a NULL terminator.
When you come to process the buffer it will contain only the last name read by a call to fscanf, or nonsense if there are zero or one lines in the file. Also, the fscanf format parameter "%s" tells fscanf to read a string up to the first whitespace (including tab or newline) character, which is probably fine for simple names, but not if you want first and second names.
This means that changing the order of the file will probably change which name is in the name buffer at the end of the routine that reads the file. This is why the value of num is different.

Using fgets() to read multiple lines. How to go to the Next line?

So I am opening a file that contains cards data for a card game I am designing for my assignment, basically each line contains 104 characters and each line is equal to a deck of card.
I'm using a char **** because of
number of decks
num of players (4)
num of cards (13)
card is represented like 9H, 3D means nine of hearts and three of diamonds, so it uses 2 characters.
I want to use fgets() to read multiple lines but I'm not sure if this works...
for loop is just the way how the deckfile is set, I just want to know if the fgets will go to the next line when it hits \n...
di->cards = (char ****)malloc(sizeof(char***) * di->numDecks);
for (i = 0; i < di->numDecks; i++) {
di->cards[i] = (char ***)malloc(sizeof(char**) * 4);
for (j = 0; j < 4, j++) {
di->cards[i][j] = (char **)malloc(sizeof(char*) * 13);
for (k = 0, k < 13, k++) {
di->cards[i][j][k] = (char *)malloc(sizeof(char) * 3);
}
}
}
for (i = 0; i < di->numDecks, i++) {
for (j = 0; j < 13, j++) {
for (k = 0; k < 4; k++) {
while ((fgets(cards[i][k][j], 3, di->deckFile)) != NULL);
}
}
}
fgets() is often called in a loop, such as this:
FILE *fp;
char buf[260];// or char *buf, then use malloc - make index size appropriate length for anticipated line len.
fp = fopen("C:\\somedir\\card.txt", "r");
while(fgets(buf, sizeof(buf), fp)) //where sizeof(buf) is the length of
//line you anticipate reading in.
{
//do something with buf here;
//The input of fgets will be NULL as soon
//as its input fp has been fully read, then exit the loop
}
fclose(fp);
Your statement while((fgets(cards[i][k][j], 3, di->deckFile)) != NULL);
has a couple of issues, one is the ; at the end. It will just loop on this one line, and not give you a chance to do anything with the line that is read before it reads the next one. Also, 3 is probably not the length of line you want to read, is it? 3 is the buffer size that will hold your card data, but the line you read from the file will be longer.
So, in addition to these points, consider the other ideas in the comments, and make changes as indicated.
[EDIT] modified to read a file with "AS3D4C...(52 cards)" 4 lines
It will fill in enough spaces for 4 decks of cards. You can use this to
see how to read in the data. strtok (used before) works only when there
are delimiters, which if you can, I would recommend using instead of
long strings. Hope this helps.
(Note, I used no [mc]alloc()'s in this example.
#include <ansi_c.h>
#define FILENAME "C:\\dev\\play\\cards.txt"
int main()
{
int i, j;
FILE *fp;
char buf[260];// or char *buf, then use malloc - make index size appropriate length for anticipated line len.
char *cardTok;
char cards[208][3]; //4 players, 4 decks, each card is 3 bytes (eg. [A|S|\0], they all need a null termination)
memset(cards, 0, 208*3);
fp = fopen(FILENAME, "r");
j = 0;
while(fgets(buf, sizeof(buf), fp)) //where buf len is initialized at 260
//and well over the anticipated 104/line, including \n etc.
{ //note, fgets() will read up to n-1 characters and place a \0 at the end
//but will stop reading sooner if it sees end of line.
for(i=0;i<52;i++) //i is card number
{
cards[i+j][0] = buf[2*i+0];
cards[i+j][1] = buf[2*i+1];
cards[i+j][2] = 0;
}
j+=52;
}
fclose(fp);
}
My text file looked like this:
9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD3D4SQhKD1H9H3D4SQhKDKD1H9H3D4SQhKD
6C9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD3D4SQhKD1H9H3D4SQhKDKD1H9H3D4SQh
2D9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD3D4SQhKD1H9H3D4SQhKDKD1H9H3D4SQh
3S9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H9H3D4SQhKD1H1H9H3D4SQhKD1H9H3D4SQhKD3D4SQhKD1H9H3D4SQhKDKD1H9H3D4S
#include <stdio.h>
char *fgets(char *s, int size, FILE *stream);
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline.
be careful with this : If a newline is read, it is stored into the buffer. A terminating null byte ('\0') is stored after the last character in the buffer.
When you want to compare line , before you need to remove \n before null byte.
If you want to read single line.
char line[100]; // here you can use char *line=malloc(100);
fgets(line,sizeof line,file_stream);
printf("%s\n",line);
if you want to read multiple lines
char lines[20][100]; // here you can use char **lines=malloc(100);
i=0;
//if you use **lines allocate size for all lines with the loop or else you can allocate size inside loop and then read.
while((fgets(lines[i],SIZE_ALLOCATED_FOR_LINE,file_stream)!=NULL) && (i<20))
{
printf("%s\n",line[i++]);
}
The documentation says,
char *fgets( char *str, int count, FILE *stream );
char *fgets( char *restrict str, int count, FILE *restrict stream );
Reads at most count - 1 characters from the given file stream and
stores them in str. The produced character string is always
NULL-terminated. Parsing stops if end-of-file occurs or a newline
character is found, in which case str will contain that newline
character.
Also,
The return value is NULL on failure.
If the failure has been caused by EOF condition, additionally sets the eof indicator (see feof()) on stdin. If the failure has been caused by some other error, sets the error indicator (see ferror()) on stdin.
Also check for feof to ensure NULL was obtained due to EOF
If you want to take the fgets input and input all of it into an array of arrays or string array how could you do that. I have tried different things but get seg faults

Resources