For me someone accepted your question too early in the staging group, I preferred to let you thinking more, and then learn more by yourself.
There are some problems in your proposal, in order from top to bottom :
In main you do not free allocated memory, even the program stops just after I encourage you to not make memory leaks. Anyway you can replace my main by yours.
You do not need to cast the result of malloc, student = malloc(sizeof(struct Student)); is enough, but warning you get 0 if there is not enough memory.
scanf("%s", student->name); is very dangerous because in case the read name is longer than 49 characters you will write out of the array, never trust on inputs, limit the read size.
student + sizeof(struct Student) does not value the address of the next Student which is student + 1, but in both case you get an address you cannot use. You need to allocate a new Student each time, as you did for the first.
I suppose the definition of Student is imposed and cannot be changed.
Here a proposal :
#include <stdio.h>
#include <stdlib.h>
struct Student
{
char name[50];
struct Student * next;
};
struct Student* studentList()
{
struct Student * head = 0; /* the end of the list */
struct Student ** tail = 0; /* &next of the last student to add at the end of the list */
for (;;) {
struct Student * student = malloc(sizeof(struct Student));
if (student == 0) {
fputs("not enough memory, stop to read\n", stderr);
return head;
}
/* read up to 49 char to have place for final 0 */
if (scanf("%49s", student->name) != 1) {
fputs("cannot read student name\n", stderr);
free(student);
return head;
}
if (head == 0) {
/* first read student */
head = student;
}
else {
/* add the new student at the end of the list, tail cannot be 0 */
*tail = student;
}
/* update the tail pointer */
tail = &student->next;
/* currently the last student */
student->next = 0;
for (;;) {
char yesno;
if (scanf(" %c", &yesno) != 1) { /* <space>%c to bypass possible spaces */
fputs("cannot read 0 or 1, force 0\n", stderr);
return head;
}
if (yesno == '0')
return head;
if (yesno == '1')
break;
fputs("enter 1 to continue to add new student, else 0\n", stderr);
}
}
}
int main()
{
struct Student * student = studentList();
while (student != 0) {
struct Student * next = student->next;
puts(student->name);
free(student);
student = next;
}
return 0;
}
Notice that supposes the name of students are not composed, so DonaldDuck rather than Donald Duck for instance.
The program indicates when something unexpected is read, but :
in case the read name is longer than 49 characters, the name is cut and the remainder will be available when 0 or 1 is supposed to be enter
when 0 or 1 is expected, to enter for instance 1azeEnter rather than 1Enter let aze to name the next student.
To avoid that the best is to flush the characters up to the newline after reading the name and 0 or 1. Notice fflush(stdin) is not guaranty and must not be used. So define an additional function making a loop using getchar() and isspace(<read char>), and also managing the EOF case, you will be able to use it in your other programs.
As you see I do not read 0 or 1 using scanf("%d", &anInt) even that seems to be the easier solution, this is because there are some problems reading a number with scanf, and the case with only 0 or 1 is trivial. I do scanf(" %c", &yesno), thanks for the space before %c that allows to bypass the possible initial spaces (space, newline, tab ...) like this is the case for %s, and then an other solution was for instance char yesno[2]; ... scanf("%s", yesno) ... and use *yesno rather than yesno
Compilation under Linux and 'standard' execution:
bruno@raspberrypi:/tmp $ gcc -g -Wall student.c
bruno@raspberrypi:/tmp $
bruno@raspberrypi:/tmp $ ./a.out
Gargi
1
bruno
1
foo
0
Gargi
bruno
foo
bruno@raspberrypi:/tmp $
to show why bypassing the rest of the line after reading names 0/1 would be better, my inputs are in bold :
bruno@raspberrypi:/tmp $ ./a.out
Gargi Chaturvedi
enter 1 to continue to add new student, else 0
enter 1 to continue to add new student, else 0
enter 1 to continue to add new student, else 0
enter 1 to continue to add new student, else 0
enter 1 to continue to add new student, else 0
enter 1 to continue to add new student, else 0
enter 1 to continue to add new student, else 0
enter 1 to continue to add new student, else 0
enter 1 to continue to add new student, else 0
enter 1 to continue to add new student, else 0
1
azertyuiopazertyuiopazertyuiopazertyuiopazertyuiop
enter 1 to continue to add new student, else 0
1
bruno
1oupps
0
Gargi
azertyuiopazertyuiopazertyuiopazertyuiopazertyuio
bruno
oupps
bruno@raspberrypi:/tmp $
char name[50];--> What is a reasonable length limit on person "Name" fields?. I'd go withchar *and allocate the name space.scanf("%s", student->name);fails to read a name that contains a space. Many surnames include prefixes that may or may not be separated by a space