What is wrong with code? What am I doing wrong?
gets(s->name);
attempts to read user input into s->name
. s->name
is a char *
that has not yet been assigned. gets()
attempts to save data to who-knows-where? Result: undefined behavior (UB).
Alternatives?
Read into a buffer and then allocated memory for a copy.
Tip: As you can, avoid scanf(), gets()
for user input and use fgets()
. C - scanf() vs gets() vs fgets().
Some code to provide an idea.
#define NAME_N 100
// return 1 on success
// return EOF on end-of-file
// return 0 other errors
int getS(Student *s) {
*s = (Student) {NULL, NULL, {0}}; // pre-fill with default values.
char buffer[NAME_N];
printf("Enter name\n");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
trim(buffer);
if (!validate_name(buffer)) {
return 0;
}
s->name = strdup(buffer);
printf("Enter last name\n");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
trim(buffer);
if (!validate_name(buffer)) {
return 0;
}
s->lastname = strdup(buffer);
printf("Enter marks\n");
for (int i = 0; i < 5; i++) {
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return EOF;
}
if (sscanf(buffer, "%d", &s->marks[i]) != 1) {
return 0;
}
}
return 1;
}
trim()
is your function to trim leading/trailing/excessive white-spaces. See also How do I trim leading/trailing whitespace in a standard way?.
strdup()
is not C standard yet very commonly available string duplication function that allocated memory and copies. Sample code
validate_name()
is placeholder code to insure some sanity in the name. Be generous in what is acceptable. Commonly acceptable characters in a name include
[A-Z, a-z, '-', ''', ' ', '.'] and many others: What are all of the allowable characters for people's names?.
Example:
// Fail a zero length name or one with controls characters in it.
bool validate_name(const char *name) {
if (*name == '\0') return false;
while (*name) {
if (iscntrl((unsigned char) *name)) return false;
name++;
}
return true;
}