Malloc Signal: SIGABRT (signal SIGABRT) problem - c

I am having a problem with my code using malloc. It has been working perfectly until an hour before. It causes on this line
temp2 = (Temp*)malloc(sizeof(Temp));
I've tried removing (Temp*) to see if that helps but it didn't. And when I searched my error message which is
untitled8(15926,0x1141ae5c0) malloc: Incorrect checksum for freed object 0x7fbff3c032e8: probably modified after being freed.
Corrupt value: 0x742e7962616c6c61
untitled8(15926,0x1141ae5c0) malloc: *** set a breakpoint in malloc_error_break to debug
Signal: SIGABRT (signal SIGABRT)
The answers I found from the internet would something to do with free(), but it errored before when I free any malloced variables.
I have main.c and task1.c and task.2, also 3 header file, and the code below is from task1.c. Never wanted to post this long ass code but since I used malloc to the other part so I would like it to be checked as well... sorry for any inconvenience reading code in advance.
typedef struct histogramTemp {
char *words;
int count;
struct histogramTemp *next;
} HistogramTemp;
typedef struct temp{
char c;
struct temp *next;
} Temp;
HistogramTemp *task1(FILE *fp, char *fname){
char textfile, *string = NULL;
Temp *tempHead = NULL, *temp1, *temp2;
HistogramTemp *uniqueWordTemp = NULL, *headTemp, *uniqueWordTempHead = NULL;
if(fp == NULL){
printf("\n\n!! Error in opening file !!\n");
printf("Program will proceed with defult 'australia.txt' file. \n");
FILE *defultFp;
defultFp = fopen("/Users/katyang/CLionProjects/untitled8/australia.txt", "r");
fp = defultFp;
}
while((textfile = fgetc(fp))!=EOF){
// save temporary word as a separate char linked list 'Temp', and save it to 'string' as a whole word
if (isupper(textfile)>0) {
temp1 = (Temp*)malloc(sizeof(Temp));
temp1->c = textfile;
temp1->next = tempHead;
tempHead = temp1;
int i=0;
while(tempHead != NULL){
string = malloc(30*sizeof(char));
strcpy(&string[i],&tempHead->c);
i++;
tempHead = tempHead->next;
}
while ((textfile = fgetc(fp))!=EOF) {
if (isalpha(textfile)>0 && !(isupper(textfile))) {
temp2 = (Temp*)malloc(sizeof(Temp));
temp2->c = textfile;
temp2->next = tempHead;
tempHead = temp2;
while(tempHead != NULL){
strcpy(&string[i],&tempHead->c);
i++;
tempHead = tempHead->next;
}
}
// use 'string', make Histogram
if(isupper(textfile) || !isalpha(textfile)){
int flag=0;
int commonWordsFlag=0;
// check if the words are in the commonWords list
for (int j = 0; j < 122 ; j++) {
if (strcmp(string, commonwords[j])==0){
commonWordsFlag++;
break;
}
}
if((strlen(string)<3) || (commonWordsFlag == 1)){
break;
}
headTemp = uniqueWordTempHead;
// compare string to uniqueWordTemp
while (uniqueWordTempHead != NULL){
// increment count if the word is in Histogram
if(strcmp(uniqueWordTempHead->words, string)==0){
uniqueWordTempHead->count++;
flag++;
uniqueWordTempHead=uniqueWordTempHead->next;
}else{
uniqueWordTempHead=uniqueWordTempHead->next;
continue;
}
}
// create new node if the word is not in Histogram
if ((uniqueWordTempHead == NULL) && (flag == 0)){
uniqueWordTempHead = headTemp;
uniqueWordTemp = (HistogramTemp*)malloc(sizeof(HistogramTemp));
uniqueWordTemp->words = string;
uniqueWordTemp->count=1;
// insert in head
uniqueWordTemp ->next = uniqueWordTempHead;
uniqueWordTempHead = uniqueWordTemp;
}else{
uniqueWordTempHead = uniqueWordTemp;
}
break;
}
}
}
}
createNewFile(fname, uniqueWordTempHead);
free(string);
free(tempHead);
return(uniqueWordTempHead);
}
so, I expected to save data in temp2 a string. It seems working with debugging which is so strange.. I have no problem when I debugged but my program ended with exit code 11 every time when I execute the program.
Edit
I added a main.c and a header file of task1() for more information.
main.c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#include "task1.h"
#include "task2.h"
int main() {
FILE *fp;
char *fname = malloc(sizeof(char));
printf("\n\n:::::::::::::: TASK 1 ::::::::::::::\n\nPlease Enter the Full Path of the file: \n");
scanf("%s", fname);
fp = fopen( fname , "r");
task1(fp, fname);
HistogramTemp *uniqueWordTempHead = task1(fp, fname);
task2(fp, fname);
free(fname);
free(uniqueWordTempHead);
return 0;
}
header file
#ifndef UNTITLED8_TASK1_H
#define UNTITLED8_TASK1_H
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
typedef struct histogramTemp {
char *words;
int count;
struct histogramTemp *next;
} HistogramTemp;
typedef struct temp{
char c;
struct temp *next;
} Temp;
HistogramTemp *task1(FILE *fp, char *fname);
int countHistogram (HistogramTemp *head);
void printHistogram (HistogramTemp *head, FILE *fp);
void createNewFile(char *userFilename, HistogramTemp *head);
#endif //UNTITLED8_TASK1_H

You cannot append just a char to a "string" like this:
strcpy(&string[i],&tempHead->c);
strcpy() expects a pointer to a "string"'s 1st char as 2nd parameter. In C a "string" is an array of char with at least one char being equal to '\0'.
Use
string[i] = tempHead->c;
instead and terminate string by doing
string[i] = '\0';
Also here
while(tempHead != NULL){
string = malloc(30*sizeof(char));
string get allocate to with each iteration overwriting the point received in the previous iteration. This introduces a huge memory leak.
More the allocation out of the loop.
So this
while(tempHead != NULL){
string = malloc(30*sizeof(char));
strcpy(&string[i],&tempHead->c);
i++;
tempHead = tempHead->next;
}
would look like this
string = malloc(30*sizeof(char));
i = 0;
while(tempHead != NULL && i < 29){ // one less to be able to store the '0' terminator
string[i] = tempHead->c;
i++;
tempHead = tempHead->next;
}
string[i] = '\0'; // store the '0' terminator

Related

Reading file and save information in a liked list using fgets and strtok in C

I'm trying to read a file which has only one line with names separated by commas, so i'm using fgets to read the line and then separate the names with strtok, then i wanted to save those names in a linked list. I'm using CodeBlocks and when i run the program it shows this message: "Process terminated with status -1073741510"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define MAX_CHAR 200
typedef struct Names{
char* name;
struct Names* next;
}Names;
Names* create_list(){
Names* aux = (Names*) malloc (sizeof(Names));
assert(aux);
aux->next = NULL;
return aux;
}
void insert_name (Names* n, char* p){
Names* aux = (Names*)malloc(sizeof(Names));
aux->name = p;
while(n->next!=NULL){
n=n->next;
}
aux->next=n->next;
n->next=aux;
}
void config(Names*p){
FILE* fp = fopen( "names.txt", "r");
if(fp == NULL){
printf("Error opening file");
return;
}
else{
char line[MAX_CHAR],*token;
fgets(line, MAX_CHAR, fp);
token = strtok(line,",");
insert_name(p,token);
while(token != NULL);{
token = strtok(NULL,",");
insert_name(p,token);
}
fclose(fp);
}
}
void print_list(Names* n){
Names* l = n->next;
while (l){
printf("%s\n",l->name);
l = l -> next;
}
}
int main()
{
Names* n;
n = create_list();
config(n);
print_list(n);
return 0;
}
You've got an infinite loop here:
while(token != NULL);{
The semicolon terminates the "body" of the while and the curly brace just opens a code block that isn't attached to any control structure. (That's legal and was a way to scope variables before C99.)
Without the semicolon, the loop is still wrong: You should only insert when you know that the token isn't NULL:
token = strtok(line,",");
while (token != NULL) {
insert_name(p,token);
token = strtok(NULL,",");
}
There are still errors in your code:
Your tokens are pointers into the local array ´line. When you leaveconfig, these pointers become invalid, becauseline` will become invalid. You should copy the strings instead just storing a pointer.
At the end of the program, you should call free for every call to malloc. In other eords, clean up your list.
I think firstly you need modify assignment of name to strcpy or memcpy and also use dynamic allocation
aux->name = (char*) malloc(strlen(p));
strcpy(aux->name, p);
or
typedef struct Names{
char name[MAX_NAME_LEN];
struct Names* next;
}Names;
//and use strcpy or memcpy in insert_name function
Hope this will help.

Printing top 10 recurring words in a file

Edited question:
Hi guys, my goal is to print the top 10 occurring words in a file, I have managed to get everything to work from reading the file to counting word occurrences and printing it, but when I implement my qsort I get a segfault. I looked over my pointers and they look okay to me, I would appreciate any feedback.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 51
struct words
{
char *ch;
int index;
struct words *pNext;
};
struct words* createWordCounter(char *ch)
{
struct words *pCounter = NULL;
pCounter = (struct words*)malloc(sizeof(char));
pCounter->ch = (char*)malloc(strlen(ch)+1);
strcpy(pCounter->ch, ch);
pCounter->index = 1;
pCounter->pNext = NULL;
return pCounter;
}
struct words *pStart = NULL;
char* removePunc(struct words* ch)
{
char *src = ch, *dst = ch;
while (*src)
{
if (ispunct((unsigned char)*src))
{
src++;
}
else if (isupper((unsigned char)*src))
{
*dst++ = tolower((unsigned char)*src);
src++;
}
else if (src == dst)
{
src++;
dst++;
}
else
{
*dst++ = *src++;
}
}
*dst = 0;
}
void addWord(char *word)
{
struct words *pCounter = NULL;
struct words *pLast = NULL;
if(pStart == NULL)
{
pStart = createWordCounter(word);
return;
}
pCounter = pStart;
while(pCounter != NULL)
{
if(strcmp(word, pCounter->ch) == 0)
{
++pCounter->index;
return;
}
pLast = pCounter;
pCounter = pCounter->pNext;
}
pLast->pNext = createWordCounter(word);
}
void printWord(struct words *pCounter)
{
printf("\n%-30s %5d\n", pCounter->ch, pCounter->index);
}
//sort
int compare (const void * a, const void * b){
struct words *A1 = (struct words *)a;
struct words *B1 = (struct words *)b;
return B1->index - A1->index;
/*
if ((A1->count - B1->count) > 0)
return -1;
else if ((A1->count - B2->count) < 0)
return 1;
else
return 0;
*/
}
int main(int argc, char * argv[])
{
struct words *pCounter = NULL;
char temp[MAX];
FILE *fpt;
if(argc == 2)
{
printf("File name is: %s\n",argv[1]);
fpt = fopen(argv[1], "r");
//fail test
if(fpt == NULL)
{
printf("cannot open file, exiting program...\n");
exit(0);
}
//get the data out of the file and insert in struct
int wordCounter = 0;
int i = 0;
int lines = 0;
while((fscanf(fpt, "%s ", &temp)) == 1)
{
removePunc(temp);
addWord(temp);
if(temp == ' ')
i++;
if(temp == '\n')
lines++;
wordCounter++;
}
/*
pCounter = pStart;
while(pCounter != NULL)
{
printWord(pCounter);
pCounter = pCounter->pNext;
}
*/
//sort
qsort(pCounter, wordCounter, sizeof(struct words), compare);
for(int j = 0; i < 10; i++)
{
printWord(pCounter);
}
}
fclose(fpt);
return 0;
}
First temp is already a pointer, so do not include '&' before it in fscanf. Second, don't skimp on buffer size (e.g. #define MAX 1024). Third, protect your array bounds with the field-width modifier and don't put trailing whitespace in your format-string.
Putting it altogether (presuming you use 1024 as MAX, you can use
fscanf(fpt, "1023%s", temp))
Well done on checking the return of fscanf during your read.
Adding to the things that have already been mentioned.
In createWordCounter(...)
pCounter = (struct words*)malloc(sizeof(char));
you are allocating memory for a char. Even though the pointer to a struct is the pointer to its first member, the first element of words is a pointer to a char. It is better to be careful and write
struct words *pCounter = malloc(sizeof *pCounter);
Also, be mindful of operator precedence.
In addWord(...) you have
++pCounter->index;
What that does is increment the pointer pCounter before accessing index. If you are trying to increment index, it should be
++(pCounter->index);
or
pCounter->index++;
I recommend striping your program down to its bare essentials and test each part one at a time systematically to narrow down the cause of your errors.
I think the main problem is the size of temp array when you try to using fscanf.
while((fscanf(fpt, "%s ", temp)) == 1)
When the length of one line is bigger than MAX, segmentation fault occur.
You can change your code like this
#define SCANF_LEN2(x) #x
#define SCANF_LEN(x) SCANF_LEN2(x)
//...
//your original code
//...
while((fscanf(fpt, "%"SCANF_LEN(MAX)"s ", temp)) == 1)
By the way, you should check
(1) compile warning about type
char* removePunc(struct words* ch)
should be char* removePunc(char *ch)
if(temp == ' ') should be if(temp[0] == ' ')
if(temp == '\n') should be if(temp[0] == '\n')
(2) malloc size
pCounter = (struct words*)malloc(sizeof(char)); should be pCounter = (struct words*)malloc(sizeof(struct words));
(3) remember free after using malloc

how to scan words and store which line scanned from in C?

im trying to make a program that read words from a file and stores each word and the line it appears at, in a list and then prints the words with the lines appeared in alphabetically, any guidance on how to do that?
so far i've put two arrays , words and lines to test my code..but im confused with how to make it read from a file with getting each word and the line it appears in..
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define LEN 7
/* Struct for word and lines that appears in */
struct wordStruct {
char *word;
char *lines;
struct wordStruct *next;
};
static int compare_words(const struct wordStruct *a, const struct wordStruct *b) {
return strcmp(a->word, b->word);
}
static struct wordStruct *insert_sorted(struct wordStruct *headptr, char *word, char *lines) {
/* Struct head */
struct wordStruct **pp = &headptr;
/* Allocate heap space for a record */
struct wordStruct *ptr = malloc(sizeof(struct wordStruct));
if (ptr == NULL) {
abort();
}
/* Assign to structure fields */
ptr->word = word;
ptr->lines = lines;
ptr->next = NULL;
/* Store words in alphabetic order */
while (*pp != NULL && compare_words(ptr, *pp) >= 0) {
pp = &(*pp)->next;
}
ptr->next = *pp;
*pp = ptr;
return headptr;
}
int main(int argc, char **argv) {
char *Arr[LEN] = { "jack", "and", "jill", "went", "up", "the", "hill" };
char *Arr2[LEN] = { "22,1,5", "24,7,3", "50", "26,66", "18,23", "32,22", "24,8" };
int i;
/* Snitialize empty list */
struct wordStruct *headptr = NULL;
/* Snitialize current */
struct wordStruct *current;
/* Insert words in list */
for (i = 0; i < LEN; i++) {
headptr = insert_sorted(headptr, Arr[i], Arr2[i]);
}
current = headptr;
while (current != NULL) {
printf("%s appears in lines %s.\n", current->word, current->lines);
current = current->next;
}
return 0;
}
i thoguht about this too, but im not sure how to merge it with my code to make it get the lines of where the word was found and make a change in Lines in wordStruct..
void read_words (FILE *f) {
char x[1024];
/* assumes no word exceeds length of 1023 */
while (fscanf(f, " %1023s", x) == 1) {
puts(x);
}
}
im confused with how to make it read from a file with getting each word and the line it appears in..
Let us define a line: All the characters up to and including a potential terminating '\n'. The first line is line 1. The last line may or may not end with a '\n'.
Let us define a word: A string consisting of non-white-space characters. For practical and security concerns, limit its size.
Using fscanf(..., "%1023s", ...) work for reading words, but since "%s" consume leading white-spaces, any '\n' are lost for counting lines. Simply pre-fscanf, one character at a time looking for '\n'.
char *GetWord1024(FILE *ifile, char *dest, uintmax_t *linefeed_count) {
// test for bad parameters
assert(ifile && dest && linefeed_count);
// consume leading white space and update count of leading line-feeds
int ch;
while (isspace(ch = fgetc(ifile))) {
if (ch == '\n') {
(*linefeed_count)++;
}
}
ungetc(ch, ifile); // put back non-whitespace character or EOF
if (fscanf(ifile, "%1023s", dest) == 1) {
return dest;
}
return NULL; // No word
}
Sample usage
int main(void) {
uintmax_t linefeed_count = 0;
char word[1024];
while (GetWord1024(stdin, word, &linefeed_count)) {
printf("Line:%ju <%s>\n", linefeed_count + 1, word);
}
return 0;
}

Segmantation Fault in C

This program will create link list from text alphabetically.
It is case-sensitive and it will eliminate the marks.
When I run the program, it gives a segmentation fault. I can't find where the problem is. I added the printf() in order to find the mistake but i can't.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct NODE {
char *word;
int count;
struct NODE *next;
}NODE;
char *get_word(FILE *fp){
printf("getWord");
char *str = (char*)malloc(sizeof(char)*100);
char c;
do {
c = fgetc(fp);
if (c == EOF)
return 0;
} while (!isalpha(c));
do {
printf("getWord");
*str++ = tolower(c);
c = fgetc(fp);
printf("Word");
} while (isalpha(c));
return str;
}
void insert(NODE* sortedList, char *word) {
printf("INSERT ");
char *str = (char*)malloc(sizeof(char)*100);
if (sortedList == NULL || word < sortedList->word) {
NODE *ekle;
ekle=(NODE*)malloc(sizeof(NODE));
strcpy(ekle->word,word);
ekle->count = 1;
ekle->next = sortedList;
sortedList = ekle;
}
else {
//
NODE *current = sortedList->next;
NODE *pre = sortedList;
while (current != NULL && word > current->word) {
pre = current;
current = current->next;
}
if (current != NULL && word == current->word) {
(current->count)++;
}
else {
NODE *ekle;
ekle=(NODE*)malloc(sizeof(NODE));
strcpy(ekle->word,word);
ekle->count = 1;
ekle->next = current;
pre->next = ekle;
}
}
}
void createList(FILE* fp,NODE *n) {
printf("CREATELIST ");
char *word;
strcpy(word,get_word(fp));
puts(word);
while (strcmp(word,"")) {
printf("Create_LİST2");
insert(n,word);
word = get_word(fp);
}
}
NODE *head;
int main(){
NODE *list=NULL;;
FILE *fp;
fp=fopen( "text.txt", "r" );
head=list;
while(!feof(fp)){
createList(fp,list);
}
while(list->next != NULL){
printf("%s", list->word);
}
return 0;
}
A major problem is this line
*str++ = tolower(c);
This changes the pointer str, so when you return str from the function it actually points beyond the string. A string which you, by the way, do not terminate.
Another major problem are these lines:
NODE *ekle;
ekle=(NODE*)malloc(sizeof(NODE));
strcpy(ekle->word,word);
Here you allocate a NODE structure, but you do not allocate memory for ekle->word, so it points to indeterminate memory. You have the above code in two places.
Equal to the above allocation problem, you have
char *word;
strcpy(word,get_word(fp));
Here too you don't allocate memory for word, so you have a pointer to indeterminate memory.
Also, in C you should not cast the return of malloc. You should also look out for warnings from the compiler, and if you don't get any from the code you have then you need to enable more warnings. Compiler warnings are often a sign of undefined behavior which is what all of the above leads to. And finally, next to the compiler I would argue that a debugger is a developers best tool. Learn to use it, it would have helped you with some of the above problems.
Here's one problem:
char c;
do {
c = fgetc(fp);
if (c == EOF)
return 0;
This is wrong; fgetc() returns int, since EOF does not fit in a char. The first line should therefore be:
int c;
Fist you have to verify if the file is correctly open. Then AFAIK the strcpy requires that destination has enough space to store the data (line 74), instead of "char *word" use "char word[255]" for instance (if you know the size limit).
Your main problem is here:
*str++ = tolower(c);
First of all, once you increment str, you no longer hold a pointer to the dynamically allocated memory. Therefore, you will not be able to release that memory at a later point in the execution of your program, which will eventually lead to memory leaks. Second, when you return str at the end of the function, you are not returning a pointer to that string as you're probably hoping to.
Additional problems are:
You are not making sure that no more than 99 characters are stored.
You are not terminating the string pointed by str with a null-character.
You are not de-allocating the string pointed by str if an EOF is encountered.
You are not using an int in order to store the return value of function fgetc.
Here is how your function should look like:
#define MAX_WORD_LEN 101
char* get_word(FILE* fp)
{
char* str = (char*)malloc(sizeof(char)*MAX_WORD_LEN);
int c,i;
do
{
c = fgetc(fp);
if (c == EOF)
{
free(str);
return 0;
}
}
while (!isalpha((char)c));
i = 0;
do
{
str[i++] = tolower((char)c);
c = fgetc(fp);
}
while (isalpha((char)c) && i < MAX_WORD_LEN-1);
str[i] = 0;
return str;
}
Please note that if a word in your file is longer than MAX_WORD_LEN-1 characters, then you will essentially "lose" the last character that was read, because it will not be stored anywhere.
not the segfault, but: you malloc str, without using or freeing it
void insert(NODE* sortedList, char *word) {
printf("INSERT ");
char *str = (char*)malloc(sizeof(char)*100);
Here i write code which may helps you to understand problem. It's not exact what as your program does but somewhat similar and easier to understand and also find your all problems solution from below code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct NODE
{
char word[100];
int count;
struct NODE *next;
}NODE;
NODE *head = NULL;
NODE *list = NULL;
void insert(char *word)
{
if (list == NULL)
{
list = calloc(1, sizeof(NODE));
if (NULL == list)
{
perror("Memory allocation failed");
return;
}
strncpy(list->word, word, 99);
list->count = 1;
list->next = NULL;
head = list;
}
else
{
list->next = calloc(1, sizeof(NODE));
if (NULL == list->next)
{
perror("Memory allocation failed");
return;
}
strncpy(list->next->word, word, 99);
list->next->count = 1;
list->next->next = NULL;
list = list->next;
}
}
void createList(FILE* fp)
{
char word[100] = {0};
while (EOF != fscanf(fp, "%99s", word))
{
if (0 < strlen(word))
{
insert(word);
}
memset(word, 0x00, 100);
}
}
int main()
{
FILE *fp = NULL;
fp = fopen("text.txt", "r");
if (NULL == fp)
{
//File is not readable
perror("text.txt file open failed");
return -1;
}
createList(fp);
list = head;
while(NULL != list)
{
printf("%s\n", list->word);
list = list->next;
}
if (NULL != fp)
{
fclose(fp);fp = NULL;
}
return 0;
}
And also create function to free all memory which is allocated in insert function.

Read strings from text file line by line and store them in linked list

My program can only read the first line of the file and then terminated. Can anyone tell me what should I modify in order to read all the lines from the file.
Below is my read_line and insert functions:
/*read_line:*/
#include <stdio.h>
#include "readline.h"
int read_line(char str[],int n)
{
int ch,i=0;
while((ch = getchar()) != '\n' && ch != EOF){
if(i < n)
str[i] = ch;
continue;
}
str[i]= '\0';
return i;
}
/*insert:*/
struct part *insert(struct part *inventory)
{
struct part *student;
student = malloc(sizeof(struct part)+1);
read_line(student -> name, NAME_LEN);
student ->next = inventory;
return student;
}
//Input file:
//B1212122 Jack Kevin 91
//B121213i Lee Van 82
//My output only contains "B1212122 Jack Kevin 91".
And my main program:
#include <stdio.h>
#include <stdlib.h>
#include "readline.c"
#define NAME_LEN 80
struct part{
char name[NAME_LEN+1];
struct part *next;
};
struct part *insert(struct part *inventory);
void print(struct part *inventory);
void print_inventory(struct part *student);
int main(void)
{
struct part *inventory = NULL;
inventory = insert(inventory);
print(inventory);
return 0;
}
You need to increase i each iteration:
int read_line(char str[],int n)
{
int ch,i=0;
while((ch = getchar()) != '\n' && ch != EOF){
if(i < n)
str[i] = ch;
i++; // Change here
}
str[i]= '\0';
return i;
}
You can update code to
int read_line(char str[],int n)
{
int ch,i=0;
while((ch = getchar()) != '\n' && ch != EOF){
if(i < n)
str[i++] = ch;
continue;
}
str[i]= '\0';
return i;
}
struct part *insert(struct part *inventory)
{
struct part *student, *first=NULL;
int i=0;
//do the reading in loop, assuming you want to read multiple lines
//as multiple student records.
do {
student = malloc(sizeof(struct part)+1);
i= read_line(student -> name, NAME_LEN);
if(i>0)
{
student ->next = inventory;
if(!first)
first = student;
}
}while(i>0);
return first; //assuming you want to return first instance of record added.
}
That is one of the reason when people generally prefer for loop over while loop because in while loop some time we forget to modify the counter variable and some time we forget to initialize variables. In for loop initialization, condition test and modification performed in the same place so the error that we generally commit in while will not perform in for loop else their is no any other advantages of for loop over while loop.

Resources