How do you assign values entered in a structure to an array? - c

I'm having a little trouble doing this. I'm creating a program that will store individuals information by ID number using a structure. I need to store then in an array then search through it with a for loop (easy). Whenever I try to compile I get an error saying request for member "blah blah" in something not a structure or union.
I'm getting this error for the final printf statement.
#include <stdio.h>
#include <stdlib.h>
struct infoStruct
{
int studentID;
int year;
int month;
int day;
int phone;
int end;
};
int main (void)
{
int students = 0;
struct infoStruct *info = NULL;
while (info.end != -1) {
students = students + 1;
printf("Enter student information (ID, day, month, year, phone)\n");
printf("Enter -1 following the phone number to end the process to continue enter 0\n");
info = malloc(sizeof(struct infoStruct) * students);
scanf("%d %d %d %d %d %d", &info.studentID, &info.day, &info.month, &info.year, &info.phone, &info.end);
}
printf("You entered %d student(s)\n", students);
printf("Enter Student ID\n");
scanf("%d", info.studentID);
}

First, your array should be of type infoStruct.
You should know the value of students. Then you can do something like:
for (int i=0;i<students;++i)
{
scanf(%d %d"[...],&infoArray[i].studentID, &infoArray[i].year[...]);
}

"info" is a pointer. So to access its values you should unreference it. As you are using array of struct you can do it in the following way:
scanf("%d %d %d %d %d %d", &info[some_counter].studentID, &info[some_counter].day, &info[some_counter].month, &info[some_counter].year, &info[come_counter].phone, &info[come_counter].end);
Also it is better to use realloc() call to change size of array of structs and fix in some way end of loop condition. Now it makes a crash because info is NULL and right before start you are trying to dereference this NULL pointer.
Loop with realloc() may look like following code:
while (true) {
printf("Enter student information (ID, day, month, year, phone)\n");
printf("To finish enter word \"end\"\n");
struct infoStruct *new_info = realloc(info, (students+1)*sizeof(struct infoStruct));
if (new_info == NULL) {
printf("Out of memory! errno = %s\n", strerror(errno));
break;
} else {
info = new_info;
}
result = scanf("%d %d %d %d %d %d",
&info[students].studentID,
&info[students].day,
&info[students].month,
&info[students].year,
&info[students].phone,
&info[students].end
);
if (result != 6) {
students--;
info = realloc(info, sizeof(struct infoStruct) * students);
break;
}
students++;
}

This:
int students = 0;
...
int infoArray [students];
...
while()
{
students = students + 1;
...
}
Will not work. You have to declare the size of your array a priori and it can't change during run-time without explicitly reallocating it.
What you can do is:
printf("What's the number of students you want?\n");
scanf("%d", &students);
...
int infoArray [students];
...
while(i++ < students)
{
// collect the data...
...
}
Since you can't change the size of the array dynamically in C without explicitly reallocating it, you will have to go for a linked list solution if you want a dynamic solution.

infoArray is declared a int. It does not provide structure elements like
infoArray.studentID. That causes the compiler to complain ... something not a structure or union.
infoArray [students]; with int students = 0; is questionable too.
You'd get (rewritten to suit the need. However, with some open questions):
#include <stdio.h>
#include <stdlib.h>
#define MAX_STUDENTS 200
typedef struct {
int studentID;
int year;
int month;
int day;
int phone;
int end;
} info_TYPE;
int main (void)
{
info_TYPE infoArray [MAX_STUDENTS];
int students = 0;
while (infoArray[students].end != -1) {
printf("Enter student information (ID, day, month, year, phone)\n");
printf("Enter -1 following the phone number to end the process to continue enter 0\n");
scanf("%d %d %d %d %d %d", &infoArray[students].studentID, &infoArray[students].day, &infoArray[students].month, &infoArray[students].year, &infoArray[students].phone, &infoArray[students].end);
students = students + 1;
if (students >= MAX_STUDENTS) break;
}
if (infoArray[students - 1].end = -1) printf("You entered %d student(s)\n", students);
printf("Enter Student ID", infoArray[students - 1].studentID);
// no idea what this line was for, presumably another previous attempt.
scanf("%d", infoArray[students - 1].studentID);
// getting tired to follow the speed at which the question is modified, presumably last edit here!
}

The compiler is complaining because
printf("Enter Student ID", infoArray.studentID);
treats infoArray.studentID as a structure member, which it is not.

Related

Segmentation fault after entering in a string from struct

so as the question says I get a segmentation fault every time I try to enter in a name for the customer. This program does compile and works until it gets to the customer name part. I'm not sure if the problem is with malloc. Could anyone show me what I am doing wrong? I've been trying to figure this out for awhile now with no luck. Thanks
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define END_OF_STRINGS '\0'
#define NEWLINE '\n'
#define MAX_CUSTOMERS 100
#define MIN_CUSTOMERS 2
#define MAX_NAME_LENGTH 20
#define DB_ALLOC_ERR 1
#define QUIT 0
struct customer
{
char *p_last_name[MAX_NAME_LENGTH + 1];
float amount_owed;
int priority;
};
void print_instructions();
int number_of_customers();
void get_accounts(struct customer *p_customer_start, int
customer_amount);
void clean_names(struct customer *p_customer_start, int
customer_amount);
void sort_names(struct customer *p_customer_start, int
customer_amount);
void print_results(struct customer *p_customer_start, int
customer_amount);
int main()
{
struct customer *p_customer;
int customer_amount;
while (print_instructions(), (customer_amount =
number_of_customers()) != QUIT)
{
if ((p_customer = (struct customer *)malloc(sizeof(*p_customer) *
MAX_NAME_LENGTH)) == NULL)
{
printf("\nError #%d occurred in main()", DB_ALLOC_ERR);
printf("\nCannot allocate memory for database of customer ");
printf("\naccountable records");
printf("\nThe program is aborting");
exit (DB_ALLOC_ERR);
}
get_accounts (p_customer, customer_amount);
clean_names (p_customer, customer_amount);
sort_names (p_customer, customer_amount);
print_results(p_customer, customer_amount);
printf("%c", NEWLINE);
free(p_customer);
}
return 0;
}
void print_instructions()
{
printf("\n\nThis program allows you to input customers which owe");
printf("\nyou money (your accounts receivable), and manage these");
printf("\naccounts in a database. You will enter the following:");
printf("\n Customer last name (1-20 characters)");
printf("\n Amount the customer owes (to the exact cent)");
printf("\n Customer priority (1=VIP, 2=Important, 3=Regular)");
printf("\nFrom 2 to 100 customers may be processed.");
return;
}
int number_of_customers()
{
int user_choice;
printf("\n\nGet the customers for the database");
printf("\n--------------------------------------------------");
do
{
printf("\nHow many customers do you have (%d to %d, %d=quit): ", MIN_CUSTOMERS, MAX_CUSTOMERS, QUIT);
scanf ("%d", &user_choice);
} while ((user_choice < MIN_CUSTOMERS ||
user_choice > MAX_CUSTOMERS) && user_choice != QUIT);
return user_choice;
}
void get_accounts(struct customer *p_customer_start, int
customer_amount)
{
struct customer *p_customer;
for (p_customer = p_customer_start; (p_customer - p_customer_start)
< customer_amount; p_customer++)
{
printf("\nCustomer number %d", (int)(p_customer -
p_customer_start + 1));
printf("\n Enter the customer's last name: ");
scanf ("%20s", p_customer->p_last_name[MAX_NAME_LENGTH + 1]);
getchar();
do
{
*p_customer->p_last_name[MAX_NAME_LENGTH] = getchar();
p_customer->p_last_name[MAX_NAME_LENGTH]++;
} while (!NEWLINE);
p_customer->p_last_name[MAX_NAME_LENGTH + 1] = END_OF_STRINGS;
printf("\n Enter the amount owed: ");
scanf ("%f", &p_customer->amount_owed);
do
{
printf("\n Enter the customer's priority (1-3): ");
scanf ("%d", &p_customer->priority);
} while (p_customer->priority < 1 || p_customer->priority > 3);
}
return;
}
void clean_names(struct customer *p_customer_start, int
customer_amount)
{
char *p_fast = p_customer_start->p_last_name[MAX_NAME_LENGTH],
*p_slow = p_customer_start->p_last_name[MAX_NAME_LENGTH];
if (tolower(*p_fast))
*p_slow++ = toupper(*p_fast);
while (*p_fast != END_OF_STRINGS)
{
if (!isspace(*p_fast) || isalpha(*p_fast))
*p_slow++ = tolower(*p_fast);
p_fast++;
}
*p_slow = END_OF_STRINGS;
return;
}
void sort_names(struct customer *p_customer_start, int
customer_amount)
{
char *p_inner[MAX_NAME_LENGTH],
*p_outer[MAX_NAME_LENGTH],
temp[MAX_NAME_LENGTH];
for (p_outer[MAX_NAME_LENGTH] = p_customer_start ->
p_last_name[MAX_NAME_LENGTH]; (p_outer - p_customer_start ->
p_last_name)
< customer_amount; p_outer[MAX_NAME_LENGTH]++)
{
for (p_inner[MAX_NAME_LENGTH] = p_outer[MAX_NAME_LENGTH + 1];
(p_inner - p_customer_start ->
p_last_name) < customer_amount; p_inner[MAX_NAME_LENGTH]++)
{
if (strcmp(p_outer[MAX_NAME_LENGTH],
p_inner[MAX_NAME_LENGTH]))
{
temp[MAX_NAME_LENGTH] = *p_outer[MAX_NAME_LENGTH];
*p_outer[MAX_NAME_LENGTH] = *p_inner[MAX_NAME_LENGTH];
*p_inner[MAX_NAME_LENGTH] = temp[MAX_NAME_LENGTH];
}
}
}
return;
}
void print_results(struct customer *p_customer_start, int
customer_amount)
{
char last_name[MAX_NAME_LENGTH];
float amount_owed = p_customer_start->amount_owed;
printf("\n Here is the accounts receivable customer database");
printf("\n=====================================================");
printf("\n Customer Name Amount Priority");
printf("\n-------------------- --------- -------------");
printf("\n %s $ %.2f ", last_name,
amount_owed);
switch (p_customer_start->priority)
{
case 1:
printf("1 (VIP)");
break;
case 2:
printf("2 (Important)");
break;
case 3:
printf("3 (Regular)");
break;
}
printf("\n\n******* End Of Customer Database Processing *******");
return;
}
i believe a start of your problem is here:
struct customer
{
char *p_last_name[MAX_NAME_LENGTH + 1];
float amount_owed;
int priority;
};
with that code you create 21 pointers to char.
What you want is character pointer to space that will hold MAX_NAME_LENGTH + 1 characters
Therefore you would want something simply like:
struct customer
{
char last_name[MAX_NAME_LENGTH + 1];
float amount_owed;
int priority;
};
I also changed p_last_name to just last_name so to the eyes it reads more logically, but you may call it whatever you like, but to say p_last_name is to imply it's a pointer which is not needed, and it reads poorly
When declaring or defining variables, you read from right to left,
it would then be an array because of [] which is 21 big, called last name and it's an array of the char data type.
Now the thing with C is that arrays and pointers have something in common, or can often be confused... because they are technically the same thing. Any array that you define, which in turn allocates space in memory, is nothing more than a pointer to the beginning of the array, that's it!
when you do something like last_name[7] then the 7 is how many jumps from the beginning of the array, which is always known as last_name in your case. The size of the jump is solely dependent upon the data type of the array when it was defined. In your case it is char which is 1 byte, so a jump of last_name[7] would be 7 bytes away from where last_name points to.
For example if the contents in memory where `last_name` points to is abcdefghijklmnopqrst
then char last_name[MAX_NAME_LENGTH + 1]; would define a variable called last_name which is technically a character pointer to contiguous chunk of memory that is MAX_NAME_LENGTH + 1 bytes because of data type char and it is a pointer to the beginning of that chunk of memory.
*last_name is the same as last_name[0] which deferences the character pointer last_name such that it returns the contents of memory which is a
*(last_name+2) is the same as last_name[2] which is c
Also, in
int main()
{
struct customer *p_customer;
int customer_amount;
this statement struct customer *p_customer; creates one pointer called p_customer that is a pointer which will point to some chunk of memory (hasn't happened yet) that is of the data type struct customer which is defined above. Ok to there. Then at
if ((p_customer = (struct customer *)malloc(sizeof(*p_customer) *
MAX_NAME_LENGTH)) == NULL)
where you use malloc to reserve some chunk of memory for what you are doing, you are really doing sizeof( a pointer )
what you should be doing is (struct customer *) malloc( sizeof( struct customer )) in addition to correctly defining a 21 byte array of characters called last_name in struct customer.
It should read out in English logically, oftentimes from right to left, if it does not then suspect a problem. Also when compiling learn to use -W it can be your friend and alert you to problems like this.
your original code is likely not allocating or reserving a large enough chunk of memory for the number of characters you type in to store in p_last_name.

C programming : Grouping multiple strings and searching for it using an Unique key

Let's say for example you are entering the personal information of a student and you create a unique ID number for each student. What I'm having problems with is grouping those strings, and storing them together, so that it can be accessed through the ID.
I tried using memory allocation, however, it did not work out.
I'm quite new to C, so I'm not exactly sure on what to do.
Here is what I used :
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct {
int LogID;
char firstname[20];
char lastname[20];
int mark;
char *subjects[100];
} student;
int reg(void);
int main(void) {
reg();
return 0;
}
//Registration function
int reg(void) {
int choice,shift,found,compare, nosub, y, sub, subcount;
char studentname[20];
FILE *fp;
FILE *fp2;
printf("Enter Student Details:\n\nStudent ID: ");
scanf("%d",&student.LogID);
printf("Name: ");
scanf("%s",student.firstname);
printf("Surname: ");
scanf("%s",student.lastname);
printf("How many subjects does the student take? ");
scanf("%d", &nosub);
//Opens a text file and prints the student's ID and firstname
fp2=fopen("subjects.txt","a+");
fprintf(fp2, "\n\n%d\t%s", student.LogID, student.firstname);
int i = 1;
size_t malloc_size = 100; //Allocating memory size to store subjects student is taking
for(i = 0; i < nosub; i++) {
student.subjects[i] = malloc(malloc_size * sizeof(char));
printf("Please enter the subject :\n(1)Mathematics\n(2)English\n(3) Social Studies\n(4)Science\n");
scanf("%d", &sub);
switch (sub) {
case (1) :
printf("Mathematics\n");
break;
case (2) :
printf("English\n");
break;
case (3) :
printf("Social Studies\n");
break;
case (4) :
printf("Science\n");
break;
}
}
for(i = 0; i < nosub; i++) { //Prints subjects to file, but it doesn't work...
fprintf(fp2,"%s\n", student.subjects[i]);
}
fclose(fp2);
free(student.subjects[i]);
student.subjects[i] = NULL;
fp=fopen("studentfile.txt","a+");
//Prints certain student Information into another file...
fprintf(fp,"\n%d\t%s\t%s\t",student.LogID,student.firstname,
student.lastname);
fclose(fp);
printf("Registration has been successful\n");
getchar();
return 0;
}
There were a number of issues I noticed and I'll address some of them, starting with the struct which I recommend defining like this:
struct studentpack {
int LogID;
char firstname[20];
char lastname[20];
int mark;
char *subjects[100];
};
And under your main function, you can define the student entry for filling.
struct studentpack student;
which will be used over and over again in your code, as you did in your example, for filling from the user input.
In the switch you really don't need any parenthesis around the case numbers.
In addition to the printf statement in each case, try something like this:
case 1:
printf("%s\n", "Mathematics");
sprintf(student.subjects + i, "%s", "Mathematics");
break;
which will fill the subjects area that you memory allocated just prior.
Finally, for grouping together the ID's I would suggest starting with something like this:
#define MAXGROUP 1000
struct studentpack *group = calloc(MAXGROUP, sizeof(struct studentpack));
int studentno = 0;
And then after you print your subjects to the file (test that it is working first due to the sprintf change) you would assign to the group like this:
if (studentno < MAXGROUP) {
memcpy(group+studentno, &student, sizeof(struct studentpack));
studentno++;
}
The above will store away the student. Next you will probably want to iterate through the group variable, accessing group[0].LogID, group[1].LogID, etc. (all the way up to a maximum of 1000) just to confirm that all your data is there in memory.
For example you could write a function that steps through looking for a particular LogID and then calls a show or display function containing printf statements to see all the values on screen.
you need an array of students
struct student{
int LogID;
char firstname[20];
char lastname[20];
int mark;
char *subjects[100];
};
struct student students[100];
you now have space for 100 students. They are students[0], students[1],...students[99]
Now you can do
int studno = 0;
While(something)
{
printf("\Enter Student Details:\n\nStudent ID: ");
scanf("%d",&(students[studno].LogID));
....
studno++;
}

typedef, can't find error in two functions

I was trying to make a program in C that would allow me to store some information about students. The idea was to make a new data type, then use it to create a few functions to manipulate the data. In particular at one point I had to find the oldest student in a group and then print out its details using another functions. The function I made that is supposed to find the maximum age in the group doesn't work. can anybody find the mistake? In particular the functions that don't work i think are calcmax and find. there are ano bugs, but when i call calcmax in main and try to print the result some random number appears and that's it. I think there is a problem with the logic in one of the loops, but I can't find it. Thanks a lot.
typedef struct{
char f[MAXIM];
char s[MAXIM];
char id[MAXIM];
char dep[MAXIM];
char g;
int age;
}student_t;
student_t mkstud(char first[],char sec[], char idn [],char de[], char sex, int eta){
student_t person;
strcpy(person.f,first);
strcpy(person.s,sec);
strcpy(person.id,idn);
strcpy(person.dep,de);
person.g = sex;
person.g = eta;
return person;
}
student_t scstud(){
char first[MAXIM],sec[MAXIM],idn[MAXIM],de[MAXIM];
char sex;
int eta;
student_t person;
printf("name ");
scanf("%s",first);
printf("surname ");
scanf("%s",sec);
printf("id ");
scanf("%s", idn);
printf("depart ");
scanf("%s",de);
printf("sex ");
scanf(" %c",&sex);
printf("age ");
scanf(" %d", &eta);
person= mkstud(first,sec,idn,de,sex,eta);
return person;
}
int calcmax(student_t *class, int length){
int diff,i;
int max[MAXIM];
diff=class[0].age-class[1].age;
if(diff>=0){
max[0]=class[0].age;
}
else if(diff<0){
max[0]=class[1].age;
}
max[1]=max[0];
for (i=0;i<length;i++){
if (max[i]>=class[i+1].age){
max[i+1]=max[i];
}
else if(max[i]<class[i+1].age){
max[i+1]=class[i+1].age;
}
}
return max[length];
}
void printdetails(student_t std){
printf("name: %s",std.f);
printf("surname: %s",std.s);
printf("ID: %s",std.id);
printf("department: %s",std.dep);
printf("gender: %c",std.g);
printf("age: %d",std.age);
}
/*void find(student_t *class, int length){
int std,i;
std = calcmax(class, length);
for(i=0;i<=length-1;i++){
if (std==class[i].age) {
printdetails(class[i]);
}
}
}*/
int main(void){
int i,j;
student_t class[6];
class[0]= mkstud("John","Bishop","s1234","inf", 'm',18);
class[1]=mkstud("Lady","Cook","s2345","Eng",'f',21);
class[2]=mkstud("James","Jackson","s3456","Eng",'m',17);
for(i=4;i<=6;i++){
printf(" student %d \n", i);
class[i-1]=scstud();
}
j=calcmax(class, 6);
printf("%d", j);
/*find(class, 3);*/
return EXIT_SUCCESS;}
Problems I see:
Minor error in mkstud. You are assigning both gender and age to the g member of the struct.
person.g = sex;
person.g = eta;
That should be:
person.g = sex;
person.age = eta;
You have not initialized the array max in calcmax.
Your logic in calcmax is flawed. If you add printf statements in the right places, you'll be able to see that max[length] is assigned an incorrect value.
int calcmax(student_t *class, int length){
int diff,i;
int max[MAXIM] = {0};
diff=class[0].age-class[1].age;
if(diff>=0){
max[0]=class[0].age;
}
else if(diff<0){
max[0]=class[1].age;
}
max[1]=max[0];
// ADDED
printf("max[0]: %d\n", max[0]);
printf("max[1]: %d\n", max[1]);
for (i=0;i<length;i++){
if (max[i]>=class[i+1].age){
max[i+1]=max[i];
// ADDED
printf("max[%d]: %d\n", i+1, max[i+1]);
}
else if(max[i]<class[i+1].age){
max[i+1]=class[i+1].age;
// ADDED
printf("max[%d]: %d\n", i+1, max[i+1]);
}
}
// ADDED
printf("max[%d]: %d\n", length, max[length]);
return max[length];
}
You can try fix that rather complex function but it can be simplified.
int calcmax(student_t *class, int length){
if ( length <= 0 )
{
return -1;
}
int max = class[0].age;
for (int i = 1; i < length; ++i )
{
if ( max < class[i].age )
{
max = class[i].age;
}
}
return max;
}

Working With Stacks in C

After many hours of working on trying to debug this code myself I'm giving up an seeking help. I created a program that is designed to hold a "record", a struct, of my choice and show I know how to utilize/manipulate them in memory. In my code I made a car inventory that allows you to add, delete, and print out structs. My struct looks like the following:
struct car{
char *make;
char *model;
int year;
int mpg;
int mileage;
int cost;
};
I use a menu system of number that allows the user to choose what to do with the struct. Anyways here's where I'm having the issue:
I can add two struct and print them all out just fine. However if I add more than two structs than I run into a seg fault. I've already tried to run GDB on it and I get the following error:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a60a03 in _IO_vfprintf_internal (s=<optimized out>, format=<optimized out>,
ap=<optimized out>) at vfprintf.c:1661
1661 vfprintf.c: No such file or directory.
As for how I am taking in this data I have 6 scanf() functions that take in the 6 characteristics of the struct, store them to a temporary variable, malloc for each string, malloc a new car struct called newCar, and set each variable inside struct to its temporary variable. If it's the first car entry then carInventory is equal to newCar. When adding another car the same process occurs except a while loop moves along a new struct called newCarInventory and stores data from carInventory using memcpy(). Below is the actual code I'm using:
void addRecord(){
newCar = (struct car *) malloc(sizeof(struct car)); //Allocates memory for a car entry
int i;
int inventoryAmountTemp = inventoryAmount; //Grabs the global value and stores it to a local variable
//Local variables used to hold onto inputted values
char make[25];
char model[25];
int year;
int mpg;
int mileage;
int cost;
printf("\nMake: ");
scanf("%s", &make);
printf("\nModel: ");
scanf("%s", &model);
printf("\nYear: ");
scanf("%i", &year);
printf("\nMiles Per Gallon: ");
scanf("%i", &mpg);
printf("\nMileage: ");
scanf("%i", &mileage);
printf("\nCost: ");
scanf("%i", &cost);
newCar->make = (char *)malloc(strlen(make)+2); //Allocates memory for string
newCar->model = (char *)malloc(strlen(model)+2);
strcpy(newCar->make, make); //Coppies string into newCar
strcpy(newCar->model, model);
newCar->year = year;
newCar->mpg = mpg;
newCar->mileage = mileage;
newCar->cost = cost;
if(inventoryAmountTemp == 0){
carInventory = newCar;
}
else{
newCarInventory = (struct car *) malloc(inventoryAmountTemp * sizeof(struct car)); //Memory made for a new Car Inventory.
headPtr = carInventory;
headPtr2 = newCarInventory;
tailPtr = newCar;
i = 0;
while(i <= inventoryAmountTemp){
memcpy(&(newCarInventory->make), &(headPtr->make), sizeof(headPtr->make));
memcpy(&(newCarInventory->model), &(headPtr->model), sizeof(headPtr->model));
memcpy(&(newCarInventory->year), &(headPtr->year), sizeof(headPtr->year));
memcpy(&(newCarInventory->mpg), &(headPtr->mpg), sizeof(headPtr->mpg));
memcpy(&(newCarInventory->mileage), &(headPtr->mileage), sizeof(headPtr->mileage));
memcpy(&(newCarInventory->cost), &(headPtr->cost), sizeof(headPtr->cost));
i++;
if(i < inventoryAmountTemp && i != inventoryAmountTemp){
headPtr++;
newCarInventory++;
}
else if(i == inventoryAmountTemp){
headPtr = tailPtr;
newCarInventory++;
}
}
newCarInventory = headPtr2;
carInventory = newCarInventory;
}
inventoryAmountTemp += 1;
accessTemp += 1;
access = accessTemp;
inventoryAmount = inventoryAmountTemp;
}
I know the issue resides from this function because I had fprintf() statements (that I took out in this code) that would test each step. The ones that would fail were the ones inside the while loop the as the loop went around the second time, of the third car entry.
Any guidance would be really appreciated!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
struct car{
char *make;
char *model;
int year;
int mpg;
int mileage;
int cost;
};
int inventoryAmount=0;
struct car* CarList=0;
char *copyString(char *str){
char *buff=0;
if(str){
int l=strlen(str);
buff=malloc(l+1);
if(buff){
for(int i=0;i<=l;i++)
buff[i]=str[i];
}
}
return buff;
}
/*_______________________________________________________
*/
void propmt(const char *msg,const char*fmt,void *output){
printf("\n%s: ",msg);
scanf(fmt,output);
return;
}
/*_______________________________________________________
*/
void addRecord(void){
struct car *newCar ;
//Local variables used to hold onto inputted values
char make[25];
char model[25];
int year;
int mpg;
int mileage;
int cost;
if(CarList){
newCar= realloc(CarList,sizeof(struct car)*(inventoryAmount+1));
}else{
newCar= malloc(sizeof(struct car));
}
if(!newCar){
printf("Failed to allocate new car\n");
exit(1);
}
CarList=newCar;
newCar=&newCar[inventoryAmount];
inventoryAmount++;
propmt("Make","%s", &make);
propmt("Model","%s", &model);
propmt("Year","%i", &year);
propmt("Miles Per Gallon","%i", &mpg);
propmt("Mileage","%i", &mileage);
propmt("Cost","%i", &cost);
newCar->make=copyString( make); //Coppies string into newCar
newCar->model=copyString( model);
newCar->year = year;
newCar->mpg = mpg;
newCar->mileage = mileage;
newCar->cost = cost;
return;
}
/*_______________________________________________________
*/
void listCars(void){
int i;
if(!inventoryAmount){
printf("\nNo cars in inventory\n");
return;
}
for(i=0;i<inventoryAmount;i++){
printf("Make: %s\n" ,CarList[i].make);
printf("Model:%s\n" ,CarList[i].model);
printf("Year:%i\n" ,CarList[i].year);
printf("Miles Per Gallon:%i\n" ,CarList[i].mpg);
printf("Mileage:%i\n" ,CarList[i].mileage);
printf("Cost:%i\n" ,CarList[i].cost);
printf("======================================\n");
}
return;
}
void pause(void){
printf("Press a key to continue");
_getch();
printf("\n");
}
int main(void){
int q;
for(;;){
_clrscr();
printf(
"1 - List cars\n"
"2 - Add new car\n"
"0 - Exit program\n");
scanf("%i",&q);
switch(q){
case 1:
listCars();
pause();
break;
case 2:
addRecord();
pause();
break;
case 0:
return 0;
break;
}
}
return 0;
}
a good sample of using malloc and realloc
Try using backtrace in gdb to see where the segmentation fault originates

Adding records with pointers to arrays

I have to create a program which adds records to a simple phone book. The code is below, but it doesn't work - function ends and then it stucks on declaring struct record x and doesn't want to display my added record - the program breaks down. When I put this part of code on the end of the function (but instead of "struct record x = array[0];" I put "struct record x = (*array)[0]") it works - record is printed. So I guess the problem is something about pointers, but I'm struggling and I really couldn't find out what's wrong. I remember that few weeks ago I created a program which was very similar but it was adding a new record to an array of integers, with fixed values and it was working well, so maybe there's something with structures that I don't know about. Thanks for any help!
I know the program isn't done yet and I know that I didn't make any action for temp_array == NULL, it'll be done after I found out what's going on.
struct record {
char f_name[SIZE];
char name[SIZE];
long int phone;
};
int add_record(struct record** array, int n)
{
struct record* temp_array = malloc((n+1) * sizeof(struct record));
if (temp_array == NULL)
{
free(temp_array);
return -1;
}
int i;
for (i=0; i < n; i++)
{
temp_array[i] = (*array)[i];
}
struct record new_record;
printf("\nAplly data.");
printf("\nFirst name: "); /*fgets(new_record.f_name, SIZE, stdin);*/ scanf("%s", &new_record.f_name);
printf("Surname: "); /*fgets(new_record.name, SIZE, stdin);*/ scanf("%s", &new_record.name);
printf("Phone number: "); scanf("%d", &new_record.phone);
temp_array[n] = new_record;
free (*array);
*array = temp_array;
//struct record x = (*array)[0];
//puts(x.f_name); puts(x.name); printf("%d", x.phone);
return 0;
}
main()
{
struct record* array; int n = 0;
int choice;
printf("\n1. Add record\n2. Delete record\n3. Find record\n0. Exit\n\nChoose action: ");
scanf("%d", &choice);
switch(choice) {
case 0: printf("\nKsiazka zostala zamknieta.\n"); return;
case 1: add_record(&array, n); n++; break;
case 2: return;
case 3: return;
default: printf("Wrong choice.\n\n"); return;
}
struct record x = array[0];
puts(x.f_name); puts(x.name); printf("%d", x.phone);
}
struct record* array=NULL;, and use %ld for long int – BLUEPIXY

Resources