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!
Related
I tried to make a small registration programm dividing it in a header, a source code containing the registration function definition and the main code.
However, i get this error message:
error: expected expression before 'struct'.
What did I do wrong? Please help I'm a beginner. Here's my main code.
#include <stdio.h>
#include <stdlib.h>
#include "registration.h"
int main()
{
int choice;
puts("Press 1 to register");
scanf("%d", &choice);
if(choice==1){
registerUser(struct generalUser user);
}
}
This my header code.
struct generalUser{
char fName[15];
char lName[20];
int id;
int bDay;
int bMonth;
int bYear;
};
struct generalUser user;
void registerUser(struct generalUser user);
Here's my code for defining the function.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void registerUser(struct generalUser user){
srand(time(NULL));
puts("Insert name");
scanf("%s", user.fName);
puts("Insert last name");
scanf("%s", user.lName);
user.id=1 + rand()%9999;
printf("You ID code is %d", &user.id);
printf("Insert date of birth in the following format: dd/mm/yy");
scanf("%d/%d/%d", &user.bDay, &user.bMonth, &user.bYear);
printf("%s %s, id %d, %d/%d/%d", user.fName, user.lName, user.id, user.bDay, user.bMonth, user.bYear);
}
There are two bugs in your source:
printf("You ID code is %d", &user.id); : please remove & because what your are printing is its value not ref
In main registerUser(struct generalUser user);, please remove struct generalUser. You are calling a function having user already declared global.
The errors that prevent my code from compiling are:
[Error] expected identifier or '(' before '.' token
[Error] expected expression before 'books'
[Error] too few arguments to function 'fread'
I'm new to C programming and programming altogether. Although I'm used to Pascal. The errors occur in all functions except in the main and void menu. This is only a part of my code.
Please can someone help me in solving these errors this program.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
char catergories[][15]={"Computer","Philosophy","Arts","Literature","Science","History"};
void menu(void);
void addbooks(void);
void deletebooks(void);
void updatebooks(void);
void findbooks(void);
void sellbooks(void);
void viewbooks(void);
int enterinfo();
int checkid(int);
void Password();
//list of global files that can be accessed from anywhere in program
FILE *fp,*ft,*fs;
//list of global variable
int s;
char findbook;
char password[10]={"dominique"};
typedef struct
{
int mm,dd,yy;
}OrderDate;
typedef struct
{
int id;
char name[35];
char author[35];
int quantity;
float price;
int count;
int shelf;
char *cat;
struct OrderDate *sold;
}books;
void addbooks(void) //funtion that add books
{
system("cls");
int i;
struct books;
printf("\n ******************************************************\n");
printf("\n \t\t ADD A BOOK");
printf("\n ******************************************************\n\n");
printf("\n SELECT THE CATERGORY OF THE BOOK:");
printf("\n 1. Computer Science, Information & General Works");
printf("\n 2. Philosophy, Psychology and Religion");
printf("\n 3. Arts and Recreation");
printf("\n 4. Literature");
printf("\n 5. Science");
printf("\n 6. History and Geography");
printf("\n 7. Back to main menu\n");
printf("\n Enter your choice:");
scanf("%d",&s);
if(s==7)
{
menu() ;
}
system("cls");
fp=fopen("BookRecords.txt","ab+");
if(enterinfo()==1)
{
books.cat=catergories[s-1]; //the error that exists here states expected identifier or '(' before '.' token
fseek(fp,0,SEEK_END);
fwrite(&books,sizeof(books),1,fp); //the error that exists here states expected expression before 'books'
fclose(fp);
printf("\n The book's information has been saved sucessfully");
printf("\n Would you like to save more information? (Y/N):");
if(getch()=='n')
{
menu();
}
else
system("cls");
addbooks();
}
}
struct books;
books is your type name. Like int or char. Thats why books.id==d won't work. You have to declare variable that is type of books. For example:
books BooksInMyShop;
Now you can use your variable in code ex.:
if(BooksInMyShop.id == currentId)
PS1: When You define:
typedef struct
{
(...)
}books;
You dont need to declare variable by struct books BooksInMyShop; simple books BooksInMyShop; will work now.
PS2: I can see in your code lots of missconceptions. For example "variable" books in every function in not shared beetween them. I guess You have to pass one instance of Your bookstore to every function or have one static global instance.
I am currently testing a program on a smaller scale to distinguish a problem when I attempt to exit the program by return 0; at the end of the main function.
Main.c
#include <stdio.h>
#include <stdlib.h>
#include "Header.h"
int main (void)
{
int i;
int Fin = 0;
Student sStu;
Array aAry;
Student *Stu = &sStu;
Array *Ary = &aAry;
InitArray(Ary, 1);
while(Fin != 2)
{
printf("Please choose a selection.\n");
printf("1. Add Student\n");
printf("2. Print Students\n");
printf("3. Exit\n");
scanf("%d", &i);
switch(i)
{
case 1:
{
AddStudent(Stu, Ary);
break;
}
case 2:
{
for(i = 0; i < Ary->Size; i++)
{
printf("%s %d\n", Stu[i].Name, Stu[i].IDn);
}
break;
}
case 3:
{
return 0;
}
}
}
}
Header.h
#ifndef HEADER_H_
#define HEADER_H_
typedef struct student
{
char Name[30];
int IDn;
}Student;
typedef struct array
{
Student *Student;
size_t Used;
size_t Size;
}Array;
void InitArray(Array *Ary, int InitSize);
void AddArray(Array *Ary);
Student AddStudent(Student *Stu, Array *Ary);
#endif
Grade.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Header.h"
void InitArray(Array *Ary, int InitSize)
{
Ary->Student = malloc(InitSize * sizeof(Student));
Ary->Used = 0;
Ary->Size = InitSize;
memset(&Ary->Student[0], 0 , sizeof(Student) * InitSize);
}
void AddArray(Array *Ary)
{
Student Stud;
if(Ary->Used == Ary->Size)
{
Ary->Size *= 2;
Ary->Student = realloc(Ary->Student, Ary->Size * sizeof(Student));
}
strcpy(Ary->Student[Ary->Used].Name, Stud.Name);
Ary->Student[Ary->Used].IDn = Stud.IDn;
Ary->Used++;
}
Student AddStudent(Student *Stu, Array *Ary)
{
int i;
printf("\nStudent ID numbers cannot be the same!\n");
printf("Please enter the student's name: ");
scanf("%s", Stu[Ary->Used].Name);
printf("Please enter the student's ID Number: ");
scanf("%d", &Stu[Ary->Used].IDn);
AddArray(Ary);
printf("\n");
return;
}
At the end of the file, when I try to return 0; I get this error:
* stack smashing detected *: ./a.out terminated
Segmentation fault (core dumped)
When I use valgrind, I get this output:
==9966== Invalid write of size 1
==9966== at 0x402C6C3: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==9966== by 0x8048687: AddArray (in /home/ctj0033/CSCE_1040/Homework/2_Homework/2_Test/a.out)
==9966== by 0x804874B: AddStudent (in /home/ctj0033/CSCE_1040/Homework/2_Homework/2_Test/a.out)
==9966== by 0x804881C: main (in /home/ctj0033/CSCE_1040/Homework/2_Homework/2_Test/a.out)
==9966== Address 0x41f804c is 0 bytes after a block of size 36 alloc'd
valgrind terminates due to an fatal error during my attempt to exit my program.
It only happens at the end and I can print the contents of the struct array properly. I have looked into realloc(); since I am fairly sure the error lies within that, however I am uncertain precisely what I have done wrong. I have attempted to alter the way I allocate the memory in InitArray(); and the way I use realloc(); but to no avail.
What have I done wrong?
Your immediate problem is that you're trying to use an "invalid pointer". (Actually, it's a completely valid pointer, it just points to a wrong place)
sStu is a Student, and Stu is a pointer to it. But when you add your second student, you write to Stu[1] - which is the space after sStu. Most likely there's something else in this space, so when you write to Stu[1], you overwrite something else. (It's unpredictable exactly what will be in that space.)
It looks like you want to use Ary->Student everywhere you have Stu.
(If you do that, you might find some more problems - such as the fact that you check if you need to expand the array after writing to the next element)
I'm trying to call a structure to a function but I'm getting the error: 'course' undeclared
The error is in the hw3func program. I typedef'd my structure and malloc'd space for it inside of main, but I don't know what I need to make my function prototype or my function call to recognize the struct? Thank you for the help in advance!!
hw3.c:
#include <stdio.h>
#include <stdlib.h>
#include "hw3func.c"
int main(void)
{
coursestruct *course = malloc(1*sizeof(coursestruct));
studentstruct *student = malloc(1*sizeof(studentstruct));
display();
menu();
return 0;
}
hw3.h:
#include <stdio.h>
#include <stdlib.h>
/*Start of prototypes*/
void display(void);
void menu(void);
void newcourse(int coursetotal, coursestruct *course);
void newstudent(int studenttotal);
/*End of prototypes*/
/*Start of initial struct declares*/
// coursestruct *course = malloc(1 * sizeof(coursestruct));
// studentstruct *student = malloc(1 * sizeof(studentstruct));
/*End of initial struct declares*/
/*Start of variables*/
int coursetotal=0;
int studenttotal=0;
/*End of variables*/
hw3struct.h:
typedef struct{
char name[50];
int id[4];
}coursestruct;
typedef struct{
char name[20];
int id[8];
}studentstruct;
hw3func.c
#include <stdio.h>
#include <stdlib.h>
#include "hw3struct.h"
#include "hw3.h"
void display(void)
{}
void menu(void)
{
int loop=0; /*Loop for the menu*/
while(loop==0)
{
int option;
printf("\n\n\nWelcome to the grade book! Select your option below.\n");
printf("1= Add a new course.\n");
printf("2= Add a new student.\n");
printf("3= Add a student to a course.\n");
printf("4= Add grades for a student in a course.\n");
printf("5= Print a list of all grades for a student in a course.\n");
printf("6= Print a list of all students in a course.\n");
printf("7= Compute the average for a student in a course.\n");
printf("8= Print a list of all courses.\n");
printf("9= Print a list of all students.\n");
printf("10= Compute the average for a course.\n");
printf("11= Store grade book to a disk file.\n");
printf("12= Load grade book from a disk file.\n");
printf("13= Exit grade book.\n");
scanf("%d",&option);
printf("\n\n\n");
if(((option>0) && (option<14)))
{
switch(option)
{
case 1:
newcourse(coursetotal,course);
break;
case 13:
loop=1;
break;
default:
break;
}
}
else
{
printf("Please input a number between 1-13.\n");
}
}
}
void newcourse(int coursetotal, coursestruct *course)
{
}
You declare coursestruct *course inside main, so it is not directly accessible from other functions (like your menu() function).
You should do some reading on variable scope in C.
In this case, the proper fix is most likely to change your function declarations to something like
void menu (coursestruct *course);
Then call it from main as menu(course);. This allows the menu function access to the variable declared inside main.
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 ;-)