Getting multiple struct entries from stdin - c

I am trying to get multiple entries for my struct via the keyboard. I think I am wrong inside of scanf but I am not sure where I am wrong. Thanks!
Here is what I have:
#include <stdio.h>
#include <math.h>
int main()
{
//define the structure
struct course
{
char title[20];
int num;
} ;
// end structure define
//define the variable
struct course classes;
printf("Enter a course title and course number");
scanf("%s %d", classes[3].title, &classes.num);
return 0;
}

Fix the code as Carl said and it works fine:
#include <stdio.h>
int main()
{
struct course
{
char title[20];
int num;
} ;
struct course class;
printf("Enter a course title and course number");
scanf("%s %d", class.title, &class.num);
printf("%s %d", class.title, class.num);
return 0;
}

There are a couple issues.
You have this struct called "classes", but it has only 1 entry - you're accessing the 3rd entry so you're running off the end.
Also, Title is 20 bytes long, but if you enter something larger in scanf(), it will just overflow. The basic scanf() structure looks ok though.
I would set it up more like this:
#include <stdio.h>
#include <math.h>
#define MAX_CLASSES 50 // how big our array of class structures is
int main()
{
//define the structure
struct course
{
char title[20];
int num;
} ;
// end structure define
//define the variable
struct course classes[MAX_CLASSES];
int nCurClass = 0; // index of the class we're entering
bool bEnterMore = true;
while (bEnterMore == true)
{
printf("Enter a course title and course number");
scanf("%s %d", classes[nCurClass].title, &classes[nCurClass].num);
// if user enters -1 or we fill up the table, quit
if (classes[nCurClass].num == -1 || nCurClass > MAX_CLASSES-1)
bEnterMore = false;
}
}
That's the basic idea. Another improvement that could be made would be checking the length of the course title before assigning it to classes[].title. But you need something to do ;-)

Related

Is this a correct usage of struct?

#include <stdio.h>
int main()
{
struct database
{
char name[10];
int number;
int roll;
};
struct database s1,s2;
printf("enter name, number , roll: ");
scanf("%c%d%d",&s1.name,&s1.number,&s1.roll);
scanf("%c%d%d",&s2.name,&s2.number,&s2.roll);
printf("Entered value is :");
printf("%c%d%d",s1.name,s1.number,s1.roll);
printf("%c%d%d",s2.name,s2.number,s2.roll);
}
I've been trying to get output but I don't know if this correct Or should I access them individually? Help would be very much appreciated! thanks :)
If you need the specific struct only within the function body, then your declaration will suffice. But, note that if you want a struct to be used throughout the program, then it needs to be defined like this:
struct database {
...
};
int main(void) {
struct database s1, s2;
...
}
Also, you're trying to accept a single char value:
scanf("%c%d%d", &name, ...);
// --^^--
Here, you are expected to get a char from the user:
scanf("%9s%d%d", name, ...);
Note: The %9s is specifically given to prevent input buffer overflow.
A nicely structured program would look like (notice comments):
#include <stdio.h>
// Don't use magical numbers for constants in the program
// The use macros for this will suffice and look a ton cleaner
#define MAX_LENGTH 64
#define FMT_LENGTH "%63s"
// Our structure
struct database {
char name[MAX_LENGTH];
int number;
int roll;
};
int main(void) {
// You are here only creating single instances of struct
struct database s1, s2;
printf("Enter name, number and roll: ");
// Always check if the values are correctly assigned to their respective
// variables, if not, print error and exit (in this context)
if (scanf(FMT_LENGTH " %d %d", s1.name, &s1.number, &s1.roll) != 3) {
printf("error: One of the values are incorrectly assigned.\n");
return 1; // Exit Failure
}
// Same with s2
printf("Name: %s | Number: %d | Roll: %d\n", s1.name, s1.number, s1.roll);
return 0;
}

Allocating memory for a struct variable using a function

As part of a larger project, I am trying to write a function that will allocate enough memory for a struct variable and assign values to its member variables after scanning them from the keyboard. In other words, I am trying to create a sort of a constructor function. The reason for this is because I think that's the best way to create a database-like program in c, where all the student_t variables will be stored in a student_t* array called classroom.
#include <stdio.h>
#include <stdlib.h>
#define N 10
#define STRLIM 50
typedef struct student{
char* name;
int age;
}student_t;
student_t* init_student(student_t* s);
int i=0;//its the array counter
student_t* classroom[N];
int main(int argc, char const *argv[]){
while(i<N){
// classroom[i]=(student*)malloc(sizeof(student));
init_student(classroom[i]);
classroom[i]->age=i;
printf("The age of student #%d is : %d \n",i,classroom[i]->age);
printf("the name of student #%d is : %s",i,classroom[i]->name);
i++;
}
printf("the size of the classroom is : %ld",sizeof(classroom));
return 0;
}//end of main()
student_t* init_student(student_t* s){
s=(student_t*)malloc(sizeof(student_t));
s->name=(char*)malloc(sizeof(char)*STRLIM);
fflush(stdin);
fgets(s->name,STRLIM,stdin);
return s;
}
Gdb ouput shown in the attached image here.
Please check out my repo.
I am guessing something about my build and datatypes is off .Thanks in advance.

"program received signal SIGSEGV, Segmentation fault" in C

I am having issues in collecting and validating a user's integer input for a grade in my program. the grade is stored in a structure along with its accompanying course name in courseRecord. there should be 2 of these structures created and stored as an array of size 2 within the studentRecord structure, where the data should be stored.
I know this is not my only problem, as I can see by the watches on the debug menu that whilst there is a substructure of a kind in studentRecord, there are not 2 as I intended. for the moment I am only working with the 1 available, and then I intend to adapt the code to include a second.
the specific error of "program recieved signal SIGSEGV, Segmentation fault", which points to when the user first enters any numerical grade leads me to believe that there is a memory allocation error somewhere. I have attempted to use the malloc function, but the fact that it is still not working means I have obviously not used it correctly. I am using the current GNU GCC compiler/linker as is available in the code:blocks software. Here is the code:
main.c
#include <stdlib.h>
#include "defs.h"
int main()
{
getGradeAverage();
return EXIT_SUCCESS;
}
defs.h
#include <stdio.h>
#include <math.h>
#define MAX_LENGTH 40
typedef struct courseRecord
{
char courseName [MAX_LENGTH+1];
int grade;
}courseRecord[2];
typedef struct studentRecord
{
char studentName [MAX_LENGTH+1];
struct courseRecord;
}studentRecord;
void getUserName ();
void getCourse (index);
void GPAPrint ();
void getGradeAverage ();
lib.c
#include "defs.h"
#include <stdbool.h>
#include <string.h>
//Gets username, assigns it to struct studentRecord.
//Known working.
void getUserName ()
{
studentRecord sr;
printf ("please enter the your name:");
scanf("%40[^\n]%*c",sr.studentName);
}
//Gets course name and grade, assigns to array of size 2 of struct courseRecord in studentRecord
void getCourse ()
{
int i;
studentRecord sr;
printf("please enter the name of course 1:");
scanf("%40[^\n]%*c",sr.courseName);
malloc(sizeof(sr.grade));
do{
printf("please enter the grade for course 1:");
scanf("%i",sr.grade);
if ((scanf("%i",sr.grade))!=1)
{
printf("sorry, that grade is in letter form. Please try again.\n");
fflush(stdin);
continue;
}
else if (sr.grade!=-2||0||2||4||6||8||10||12);
{
printf("sorry, that grade is not on the scale. Please try again.\n");
fflush(stdin);
continue;
}
} while(true);
}
void GPAPrint ()
{
int GPA;
studentRecord sr;
/*
GPA=(sr.grade[1]+sr.grade[2])/2
printf("Student name: %s\n",&sr.studentName\n\n);
printf("Course: %s\nGrade:%i\n"sr.coursename[1], sr.grade[1])
printf("Course: %s\nGrade:%i\n"sr.coursename[2], sr.grade[2])
printf("total GPA is %i",GPA)
*/
}
void getGradeAverage ()
{
getUserName();
getCourse();
GPAPrint();
}
thanks for your help in advance!

Can't more than two strings compare?

If we compared integers we would assign one of them as the largest/smallest one.
However, when I try comparing more than two strings, I can't manage assaigment.
In my code "for loop" compares two of the strings. This is good method but I need to compare one of them to the others individually. (I can predict that I need to use two for loop, but also I can't implement) What is your suggestions?
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct wordSorting
{
char name[15];
int i = 0;
};
int main()
{
wordSorting *wordElement = (wordSorting *)malloc(sizeof(wordSorting));
wordElement = (wordSorting *)malloc(sizeof(wordSorting));
printf("-- Enter three person name --\n\n");
for (wordElement->i = 0; wordElement->i < 3; wordElement->i++)
{
printf("Enter %d. person name: ", wordElement->i + 1);
scanf("%s", wordElement[wordElement->i].name);
}
printf("\n");
for (wordElement->i = 0; wordElement->i < 3; wordElement->i++)
{
if ((strcmp(wordElement[wordElement->i].name, wordElement[wordElement->i + 1].name))<0)
{
printf("%s", wordElement[wordElement->i].name);
}
}
}
First
typedef struct wordSorting
{
char name[15];
int i = 0;
};
Members of typedef/struct cannot be initied.
That is not the way to define a typedef, change it as:
typedef struct
{
char name[15];
int i;
}wordSorting;
Second:
wordElement = (wordSorting *)malloc(sizeof(wordSorting));
makes no sense. malloc returns void pointer, and you already init your variable at the first element in the first line of code.
And, as someone edited: do not cast malloc return, please.
Third, :
wordSorting *wordElement = (wordSorting *)malloc(sizeof(wordSorting));
wordElement = (wordSorting *)malloc(sizeof(wordSorting));
printf("-- Enter three person name --\n\n");
for (wordElement->i = 0; wordElement->i < 3; wordElement->i++)
{
printf("Enter %d. person name: ", wordElement->i + 1);
scanf("%s", wordElement[wordElement->i].name);
}
You are allocating space for one element, no array are defined then wordElement[wordElement->i].name is undefined Behaviour.
Finally
I don't know what compiler are you using, but gcc cannot compile such a bad code full of errors...
Suggestion.
What I think you need is to use array, but you must allocate the number of member you need, by:
wordSorting *wordElement = malloc(sizeof(wordSorting)*num_of_elements);
or simply, using a local array:
wordSorting wordElement[num_of_elements];

scanf doesn't take all in inputs

I supposed to perform a project which allocate N bytes of memory of struct person
and scanning f every person's name initial_money and some other variables
the problem for me when i run the code is that it is terminating at some point of taking input process and i don't why
also this problem faced me yesterday in code forces contest
#include <stdio.h>
#include <stdlib.h>
struct person
{
char name[15];
int initial_money;
int g;
int final_money;
int money;
};
int main()
{
int NP,i,j;
char target1[15];
scanf("%d",&NP);
struct person *p=malloc(NP*sizeof(struct person));
for(i=0;i<NP;i++)
{
scanf("%s",(p+i)->name);
}
for(i=0;i<NP;i++)
{
scanf("%s",target1);
for(j=0;j<NP;j++)
{
if((p+j)->name==target1)
{
scanf("%d%d",(p+j)->initial_money,(p+j)->g);
(p+j)->final_money=(p+j)->initial_money%(p+j)->g;
}
}
}
for(i=0;i<NP;i++)
{
printf("%s %d %d %d",(p+i)->name,(p+i)->initial_money,(p+i)->g,(p+i)->final_money);
}
return 0;
}
The scanf function need pointers for inputed values.
The line:
scanf("%d%d",(p+j)->initial_money,(p+j)->g);
Should be:
scanf("%d %d",&(p+j)->initial_money,&(p+j)->g);
When comparing strings you usually can't compare pointers directly:
if((p+j)->name==target1)
shoul be:
if(strcmp((p+j)->name, target1) == 0)

Resources