Quick issue with my code. Please look in the function enter(). When I request the name, and use gets(), it just skips it as if nothing was there, and jumps to requesting the age. What am I doing incorrectly?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define RECORDS 30
#define LEN 20
/*Questions
Formatting display() - can we use spaces to format?
Is the patient structure supposed to be global or local in enter()?
Why doesn't printf("name: "); scanf("%s", name); require &name?
Make sure you account for first and last names, use getline or something
*/
void enter();
struct patient
{
char name[LEN];
int age;
double highBP, lowBP, riskFactor;
};
struct patient * db[RECORDS];
int counter = 0;
main()
{
int flag = 1;
while (flag == 1)
{
printf("---------------------------------------------------------\n");
printf("|\t(N)ew record\t(D)isplay db\t(U)pdate record |\n");
printf("|\t(L)oad disk\t(W)rite disk\t(E)mpty disk |\n");
printf("|\t(S)ort db\t(C)lear db\t(Q)uit |\n");
printf("---------------------------------------------------------\n");
printf("choose one: ");
char selection, selectionstr[3];
scanf("%s",selectionstr);
selection = selectionstr[0];
//printf("selection %c\n", selection);
if ((selection == 'n') || (selection == 'N'))
{
//New record
enter();
}
// Options omitted...
else
{
printf("not a vaild input\n");
}
}
}
void enter()
{
if (counter < 30)
{
FILE *fptr;
fptr = fopen("db.txt", "a");
char name[LEN];
int age;
double highBP, lowBP;
printf("name: "); //scanf("%s", name);
gets(name);
printf("age: "); scanf("%d", &age);
printf("high bp: "); scanf("%lf", &highBP);
printf("low bp: "); scanf("%lf", &lowBP);
struct patient temp;
strcpy(temp.name, name);
temp.age = age;
temp.highBP = highBP;
temp.lowBP = lowBP;
if ((highBP < 120) && (lowBP < 80))
temp.riskFactor = 0;
if (((highBP <= 120) && ((lowBP > 80) && (lowBP <= 90))) || ((highBP <= 80) && ((lowBP > 120) && (lowBP <= 130))))
temp.riskFactor = 1;
if (((highBP <= 120) && ((lowBP > 90) && (lowBP <= 100))) || ((highBP <= 80) && ((lowBP > 130) && (lowBP <= 140))))
temp.riskFactor = 4;
else
temp.riskFactor = 5;
if ((temp.riskFactor > 0) && (temp.age > 50))
temp.riskFactor += 0.5;
db[counter] = &temp;
//fprintf(fptr, "%s, %d, %f, %f, %f\n", db[counter]->name, db[counter]->age, db[counter]->highBP, db[counter]->lowBP, db[counter]->riskFactor);
printf("%s, %d, %f, %f, %f\n", db[counter]->name, db[counter]->age, db[counter]->highBP, db[counter]->lowBP, db[counter]->riskFactor);
counter++;
fclose(fptr);
}
else
printf("database full");
/*db[counter] = (struct patient *) malloc(sizeof(struct patient));
printf("name: "); scanf("%s", (*db[counter]).name);
printf("age: "); scanf("%d", (*db[counter]).age);
printf("high bp: "); scanf("%d", (*db[counter]).highBP);
printf("low bp: "); scanf("%d", (*db[counter]).lowBP);
//db[counter] = &temp;
printf("%d", sizeof(db[counter]));
//printf("%s", (db[counter])->name);
printf("%s, %d, %f, %f\n", db[counter]->name, db[counter]->age, db[counter]->highBP, db[counter]->lowBP);
counter++;*/
}
Main Problems
Do not use
gets(), ever. Not even in toy programs. It is a bad habit to get into. It cannot be used safely, ultimately, because you cannot tell when the input is going to overflow the buffer you provide.Use
fgets()instead, and remember to remove the trailing newline it leaves behind (the onegets()removes).Your problem is that the previous input with
scanf()didn’t read the newline, sogets()reads to the first newline – giving you an empty string. You’d run into the same problem on the next iteration, too, because you read the blood pressure withscanf().Auxilliary Problems
You do not check that the inputs succeeded; always check the return value from
scanf()to ensure that you got the inputs you expected. You’d be getting errors because the name can’t be interpreted as a number.You should get into the habit of writing code that declares functions with prototypes; the notation:
says “there is a function
enter()that returns no value and takes an indeterminate argument list – any set of arguments is OK, but it isn’t a variable argument list function”. By contrast:says “there is a function
enter()that returns no value and takes no arguments”.Also, you should explicitly define the return type of
main()asint. It has been more than a decade since the C standard required explicit return types on all function definitions.Incipient Problem
Once you get over the data scanning problem, you will find that you are not allocating space properly for your records. Your array is:
In the loop, you have:
The troubles are two-fold. You are re-using the same space for each patient record, and the pointer you are storing goes out of scope when
enter()exits. The simplest fix is to change the global variable to:You can then do away with the
tempvariable, and simply initialize the appropriate entry indb. Alternatively, you can keeptempbut do structure assignment instead of pointer assignment: