You have several errors, but the primary issue with your input is you have mixed fgets()
(which you should use for every input) and scanf()
. When you mix use of fgets()
and scanf()
, you must understand that fgets()
will read and include the '\n'
generated by the user pressing Enter in the buffer it fills. scanf()
with the "%s"
conversion specifier does not.
However, there are two problems with scanf()
here.
- you fail to include a field-width modifier, making
scanf()
prone to exploit by buffer-overrun and using it that way is no safer than using gets()
. See: Why gets() is so dangerous it should never be used!
- You mix
fgets()
and scanf()
in attempt to avoid the '\n'
at the end of yr
and stid
as well as in your read of psswrd
where you should simply have read with fgets()
and trimmed the '\n'
from the end of the input using strcspn()
.
Let's look at the example using only fgets()
and see if it can be made to work properly.
First, instead of seven different string variables, let's clean that up by placing each of the strings in a struct
so if you need to hold more than one student's data, you can simply use an array of struct, e.g.
#include <stdio.h>
#include <string.h>
#define MAXLN 10 /* if you need a constant, #define one (or more) */
#define MAXID 15
#define MAXFN 25
#define MAXPW 50
typedef struct { /* struct to hold student information */
char addr[MAXPW], /* typedef for convenience */
cr[MAXPW],
psswrd[MAXPW],
fname[MAXFN],
stid[MAXID],
lname[MAXLN],
yr[MAXLN];
} student_t;
...
Now simply declare an instance of the struct (initialized to all zero) and a buffer to hold input of the verification password:
...
int main (void) {
char buf[MAXPW] = ""; /* buffer for input of password conf */
student_t student = {0}; /* instance of struct initialized all zero */
...
Now simply read the data into your struct using fgets()
and trim the '\n'
read and included by fgets()
using strcspn()
as follows:
...
fputs ("Welcome to the Code!\n"
"Please Input your First Name: ", stdout);
if (!fgets (student.fname, MAXFN, stdin)) {
return 0;
}
student.fname[strcspn (student.fname, "\n")] = 0; /* trim \n from end */
...
Your remaining input happens the exact same way:
...
fputs ("Please Input your Last Name: ", stdout);
if (!fgets (student.lname, MAXLN, stdin)) {
return 0;
}
student.lname[strcspn (student.lname, "\n")] = 0;
fputs ("Please Input your address: ", stdout);
if (!fgets (student.addr, MAXPW, stdin)) {
return 0;
}
student.addr[strcspn (student.addr, "\n")] = 0;
fputs ("Please Input your Course: ", stdout);
if (!fgets (student.cr, 50, stdin)) {
return 0;
}
student.cr[strcspn (student.cr, "\n")] = 0;
fputs ("Please Input your College Year & Section: ", stdout);
if (!fgets (student.yr, MAXLN, stdin)) {
return 0;
}
student.yr[strcspn (student.yr, "\n")] = 0;
fputs ("Please Input your Student ID: ", stdout);
if (!fgets (student.stid, MAXID, stdin)) {
return 0;
}
student.stid[strcspn (student.stid, "\n")] = 0;
...
(note: there are no conversions requiring the use of printf()
, simply use fputs()
for output when you want end-of-line control, or puts()
if you simply want a '\n'
added)
Now create your combined password from yr
and stid
:
...
strcpy (student.psswrd, student.yr); /* fill student password */
strcat (student.psswrd, student.stid);
...
When you output data, you do not need one printf()
(or fputs()
or puts()
) per-line, you simply need one call per continuous block of output, e.g.
...
printf ("\nYour Details:\n"
"First Name: %s\n"
"Last Name: %s\n"
"Address: %s\n"
"College Year: %s\n"
"Course: %s\n"
"Student ID: %s\n"
"Your Password: %s\n", student.fname, student.lname,
student.addr, student.yr, student.cr, student.stid,
student.psswrd);
...
For your verification loop, simply loop continually until a valid verification password is provided, and break
the verification-loop at that time, e.g.
...
while (1) {
fputs ("\nInput your New Password to Get Verified: ", stdout);
if (!fgets (buf, MAXPW, stdin)) {
return 0;
}
buf[strcspn (buf, "\n")] = 0;
if (strcmp (buf, student.psswrd) == 0) { /* check password */
break;
}
fputs (" error: verification failed, passwords do not match.\n",
stderr);
}
...
That's it aside for your closing:
...
puts ("Verification Successful! \nThank you for Using the Code!");
}
For convenience, the entire code (which you can copy/paste from above) is:
#include <stdio.h>
#include <string.h>
#define MAXLN 10 /* if you need a constant, #define one (or more) */
#define MAXID 15
#define MAXFN 25
#define MAXPW 50
typedef struct { /* struct to hold student information */
char addr[MAXPW], /* typedef for convenience */
cr[MAXPW],
psswrd[MAXPW],
fname[MAXFN],
stid[MAXID],
lname[MAXLN],
yr[MAXLN];
} student_t;
int main (void) {
char buf[MAXPW] = ""; /* buffer for input of password conf */
student_t student = {0}; /* instance of struct initialized all zero */
fputs ("Welcome to the Code!\n"
"Please Input your First Name: ", stdout);
if (!fgets (student.fname, MAXFN, stdin)) {
return 0;
}
student.fname[strcspn (student.fname, "\n")] = 0; /* trim \n from end */
fputs ("Please Input your Last Name: ", stdout);
if (!fgets (student.lname, MAXLN, stdin)) {
return 0;
}
student.lname[strcspn (student.lname, "\n")] = 0;
fputs ("Please Input your address: ", stdout);
if (!fgets (student.addr, MAXPW, stdin)) {
return 0;
}
student.addr[strcspn (student.addr, "\n")] = 0;
fputs ("Please Input your Course: ", stdout);
if (!fgets (student.cr, 50, stdin)) {
return 0;
}
student.cr[strcspn (student.cr, "\n")] = 0;
fputs ("Please Input your College Year & Section: ", stdout);
if (!fgets (student.yr, MAXLN, stdin)) {
return 0;
}
student.yr[strcspn (student.yr, "\n")] = 0;
fputs ("Please Input your Student ID: ", stdout);
if (!fgets (student.stid, MAXID, stdin)) {
return 0;
}
student.stid[strcspn (student.stid, "\n")] = 0;
strcpy (student.psswrd, student.yr); /* fill student password */
strcat (student.psswrd, student.stid);
printf ("\nYour Details:\n"
"First Name: %s\n"
"Last Name: %s\n"
"Address: %s\n"
"College Year: %s\n"
"Course: %s\n"
"Student ID: %s\n"
"Your Password: %s\n", student.fname, student.lname,
student.addr, student.yr, student.cr, student.stid,
student.psswrd);
while (1) {
fputs ("\nInput your New Password to Get Verified: ", stdout);
if (!fgets (buf, MAXPW, stdin)) {
return 0;
}
buf[strcspn (buf, "\n")] = 0;
if (strcmp (buf, student.psswrd) == 0) { /* check password */
break;
}
fputs (" error: verification failed, passwords do not match.\n",
stderr);
}
puts ("Verification Successful! \nThank you for Using the Code!");
}
Example Use/Output
$ ./bin/student_verification
Welcome to the Code!
Please Input your First Name: Walt
Please Input your Last Name: Disney
Please Input your address: 111 Tune Ln.
Please Input your Course: Comedy
Please Input your College Year & Section: 22bs
Please Input your Student ID: 3123
Your Details:
First Name: Walt
Last Name: Disney
Address: 111 Tune Ln.
College Year: 22bs
Course: Comedy
Student ID: 3123
Your Password: 22bs3123
Input your New Password to Get Verified: 22bs3123
Verification Successful!
Thank you for Using the Code!
Look things over and let me know if you have further questions.