c database program using structs - c

I'm make a program in c that display a database using structures, I'm kinda new to programming also I know c++ and i make the program also for c++ but I have a problem in both programs. I will post only the c code. So the program works fine until I saw that is not printed the values I entered, it prints random values(it's garbage memory I guess). I don't know why this is working have a look:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
typedef struct database{
char dataname[32],date[32];
int number_employers;
float profit;
double salary;
}database;
void new_company(database x);
void show_company(database x);
int main()
{
database Tarom,Wizzair;
new_company(Tarom);
system("cls");
new_company(Wizzair);
system("cls");
show_company(Tarom);
show_company(Wizzair);
return 0;
}
void new_company(database x){
printf("Enter company name: ");
scanf("%s",&x.dataname);
printf("\nEnter company date: ");
scanf("%s",&x.date);
printf("\nEnter number of employers:");
scanf("%d",&x.number_employers);
printf("\nEnter the average salary of employers:");
scanf("%f",&x.salary);
printf("\nEnter the company profit(in proccent):");
scanf("%f",&x.profit);
}
void show_company(database y){
printf("Company name:%s\n",y.dataname);
printf("Company date:%s\n",y.date);
printf("Number of employers:%d\n",y.number_employers);
printf("Average salary of employers:%f\n",y.salary);
printf("Company profit:%f\n***************************\n",y.profit);
}

void new_company(database x){
You passed the object by value, so the function gets a local copy. Any changes to the object made inside the function affect only the local copy, not the original. That is your problem.
In C++, the correction to that problem is simpler. You just change the signature of the function to
void new_company(database& x){
In C, the change is more difficult. You need & in front of the object name where the caller passes it to the function, and you need * in front of the name in the function signature, and you need to change all the . used to access members of the object inside the function to ->

Because you're passing the database object by value, so a copy of the (uninitialized) dictionary objects is being passed in, and it's this copy that's being updated by new company. Pass in the address of the dictionaries, e.g.
new_company(&Tarom);
and change new_company definition to take a pointer to a database, like:
void new_company(database* x){

Related

Trouble in C program for getting output [duplicate]

This question already has answers here:
Parameter Passing in C - Pointers, Addresses, Aliases
(2 answers)
Closed 4 years ago.
This is a simple program
#include<stdio.h>
void get(int,int);
void main()
{
int a,b;
get(a,b);
printf("In main");
printf("%d",a);
}
void get(int m,int n)
{
printf("enter the value");
scanf("%d%d",&m,&n);
}
and I got an output is
enter the value
4
5
in main:
0
Why is the value of m in get() not assigned to a in main()? What's my mistake?
You're passing your main variables via value. Read about how you can pass by reference, here. scanf requires addresses of variables in order to modify them; so you need to pass their addresses like this:
get(&a, &b);
And you can modify your get() method like this:
void get(int* pM,int* pN) {
printf("enter the value");
scanf("%d%d, pM, pN);
}
Your scanf reads into function local variables which store the values you give as parameters to the function.
Their values are not visible in the variables you give as parameters to the function.
You probably want to use pointers to variables as parameters, then the read values can end up in the variables pointed to by those pointer-parameters.
This is basically happening due to scope of variables, since integers are passed by value and not by reference.
You need to return values of a and b for them to be present in main().
see more here
https://www.tutorialspoint.com/cprogramming/c_function_call_by_value.htm
#inlcude<stdio.h>
int get(int,int);
void main() {
int a,b;
a = get(a,b);
printf("In main");
printf("%d",a);
}
int get(int m,int n){
printf("enter the value");
scanf("%d%d,&m,&n);
return m;
}
Enter the value
10 20
In main
10
Also, read about indenting the code so that it's more readable.
Why is the value of m in get() not assigned to a in main()? What's my mistake?
First, you need to understand the concept of parameter passing in C.
[If you are not aware of formal and actual parameters, check this]
Technically, everything in C is pass-by-value. Here,
get(a,b);
you are passing the value of a and b variable to function get(). The value of actual parameter a and b will be copied to formal parameters m and n [in this case, the value of a and b variable is garbage since you have not initialized them]. Any modification to the value of formal parameters (m and n) in the calling function will not reflect in the actual parameters (a and b) because formal parameter storage is separate. Hence, the value of m in get() does not assigned to a in main().
Below part of the answer is based on the assumption that you are aware of the concept of pointers in C language. If not, I would suggest to pick choose a good C language book/tutorial and go through the concept of pointers.
C language provides a facility to pass a pointer to a function which is also pass-by-value only. It copies the value of the pointer, i.e. the address, to the function formal parameters and you can access the value stored at that address by dereferencing the pointer. Hence, any changes made in the value at the address passed will reflect in the calling function actual parameters.
So, you can do:
#include<stdio.h>
void get(int *, int *);
int main()
{
int a, b;
get(&a, &b);
printf("In main\n");
printf("a : %d, b = %d\n", a, b);
}
void get(int *m,int *n)
{
printf("Enter the value:\n");
scanf("%d%d", m, n); // m holds the address of a and n holds the address of b variable.
printf("Value entered:\n");
printf("%d %d\n", *m, *n); //dereferencing the pointer m and n
}

Pointers in C for a rookie

I am just starting to learn programming for a unit I am doing in my engineering course and I have come across pointers. I just wanted some reassurance that I actually understand the concept correctly in terms of using a pointer as an argument in a function. If I understand it correctly, you pass a pointer to an address of a variable you would like to be altered by a separate function called, even though it is a local variable within the scope of the calling function. Does that make sense? I have an example from my text book which I re-wrote. The only thing is they gave it in two incomplete parts and I put it together, filled in the blanks and added the final printf statement in the main function. I'll paste it here:
#include <stdio.h>
#include <stdlib.h>
#define READ_OK 0
#define READ_ERROR 1
int read_num(int lo, int hi, int *num);
int main(int argc, char *argv[])
{
int lo = 0, hi = 0, *num, val;
printf("Please enter a lower bound and an upper bound for your range,respectively\nLower: ");
scanf("%d", &lo);
printf("Upper: ");
scanf("%d", &hi);
num = &val;
if(read_num(lo,hi, &val) != READ_OK)
{
printf("Read error, program abort\n");
exit(EXIT_FAILURE);
}
else
{
printf("You entered %d, press any key to continue: \n", val);
getchar();
}
return 0;
}
int read_num(int lo, int hi, int *num)
{
int next;
printf("Enter a number between %d and %d: ", lo, hi);
while(scanf("%d", &next)==1)
{
if (lo<=next && next<=hi)
{
*num = next;
return READ_OK;
}
printf("%d is not between %d and %d\nTry again: ", next, lo, hi);
}
return READ_ERROR;
}
So is my understanding correct? "val" gets modified in read_num() by passing it's address in the form of pointer "*num", in which the the value for "next" is then written?
PS: is this syntax correct?
PPS: What would this process specifically be called?
Thanks a bunch for any help :)
The *num is not necessary inside the main() function. As you are passing the address of the val inside the read_num() , so any changes from the read_num() will also affect the value inside main() as you are working with the address.
In your program you have basically use two different pointers- one is inside main which is num, and another inside read_num() which is also num, for more understanding see the scope of a variable in c. As the val is inside main so you don't need to use pointer here, because you have the access of changing the value from the main as it is local to it. You will need pointer when you will be changing the value of val outside from the main, or from outside of the scope of the variable.

Function to save data as struct on C

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
typedef struct equipamento {
int codDipositivo;
char nomeEquipamento[40];
char newVar[50];
}Equipamento;
insert(int n, int cat, Equipamento eq[])
{
int codigo;
char newVar[40];
printf("\nNew Var: ");
scanf("%s",&newVar);
eq[n].codDipositivo=newVar;
}
main()
{
Equipamento equipamento[MAX_EQ_DSP];
...a bunch of scanfs
scanf("%d",&n);
scanf("%d",&pr);
insert(n, pr, equipamento);
}
This is a sample of what I have.
on main I have a bunch of scanfs which will update the data showing on the screen but now I want to pass that data into a structure and ask for additional information.
I'm trying to use the updated code but for some reason, instead of 39 chars, it breaks down (returns to the main cycle) after the first char
printf("\nNome do Equipamento: ");
gets(nome);
strcpy(eq[n].nomeEquipamento, nome);
Your problem is this line:
eq[n].codDipositivo=newVar;
In C, you cannot assign arrays, you need to copy them element for element. Remember that C has no string data type, a string is just a NUL-terminated array of char. Luckily there is a function in the C library to help us, strcpy.
strcpy(eq[n].codDipositivo, newVar);
To get the declaration of strcpyyou need to add the following include at the top of your code:
#include <string.h>

Declaring arrays in c language without initial size

Write a program to manipulate the temperature details as given below.
- Input the number of days to be calculated. – Main function
- Input temperature in Celsius – input function
- Convert the temperature from Celsius to Fahrenheit.- Separate function
- find the average temperature in Fahrenheit.
how can I make this program without initial size of array ??
#include<stdio.h>
#include<conio.h>
void input(int);
int temp[10];
int d;
void main()
{
int x=0;
float avg=0,t=0;
printf("\nHow many days : ");
scanf("%d",&d);
input(d);
conv();
for(x=0;x<d;x++)
{
t=t+temp[x];
}
avg=t/d;
printf("Avarage is %f",avg);
getch();
}
void input(int d)
{
int x=0;
for(x=0;x<d;x++)
{
printf("Input temperature in Celsius for #%d day",x+1);
scanf("%d",&temp[x]);
}
}
void conv()
{
int x=0;
for(x=0;x<d;x++)
{
temp[x]=1.8*temp[x]+32;
}
}
In C arrays and pointers are closely related. In fact, by design an array is just a syntax convention for accessing a pointer to an allocated memory. *(see note for more details below)
So in C the statement
anyarray[n]
is the same as
*(anyarray+n)
Using pointer arithmetic.
You don't really have to worry about the details to make it "work" as it is designed to be somewhat intuitive.
Just create a pointer, and allocate the memory and then access it like as an array.
Here is some examples --
int *temp = null; // this will be our array
// allocate space for 10 items
temp = malloc(sizeof(int)*10);
// reference the first element of temp
temp[0] = 70;
// free the memory when done
free(temp);
Remember -- if you access outside of the allocated area you will have unknown effects.
To be clear it is the indexing operator ([ ]) that is translated to pointer arithmetic. This is not an array in the modern sense of the
type. Whether (or not) the pointer involved points to (dynamically) allocated
memory is inconsequential to how this operator works. In a more modern language you would be able to operate on the array as an abstract type (to see how big it is, for example), you can't do this in C.
An array without an initial size is basically just a pointer. In order to dynamically set the size of the array, you need to use the malloc() or calloc() functions. These will allocate a specified amount of bytes of memory.
In your code above, declare temp as an int pointer
int *temp;
Then allocate space for it using malloc() or calloc(). The argument that these functions take is is the number of bytes of memory to allocate. In this case, you want enough space for d ints. So...
temp = malloc(d * sizeof(int));
malloc returns a pointer to the first byte in the block of memory that was just allocated. Regular arrays are simply pointers to the first byte in a sectioned off block of memory, which is exactly what temp is now. Thus, you can treat the temp pointer as an array! Like so:
temp[1] = 10;
int foo = temp[1];
printf("%d", foo);
Outputs
10
You will need to declare temp as an int pointer (instead of an int array). Then, you can use malloc in your main (after your first scanf):
temp = malloc(d * sizeof(int));
If your compiler supports c99, then simply use VLA(variable length array).Use like this:
void input(int);
int d;
void main()
{
int x=0;
float avg=0,t=0;
printf("\nHow many days : ");
scanf("%d",&d);
int temp[d];
input(d);
conv();
for(x=0;x<d;x++)
{
t=t+temp[x];
}
avg=t/d;
printf("Avarage is %f",avg);
getch();
}
Now temp[] is defined inside main() after date input.
1-add #include<stdlib.h> at the top of your file. Then modify the conv() code as follows:
2- modify temp declaration as follows (global variable):
int *temp;
3- modify input(int d) function as follows (tested on Visual Studio 2010):
void input(int d)
{
int x=0;
temp=(int*)malloc(sizeof(int)*d);
for(x=0;x<d;x++)
{
printf("Input temperature in Celsius for #%d day",x+1);
scanf("%d",&temp[x]);
}
}
Allocate the "array" dynamically on the heap after you read the size.
I didn't change anything else so you may see it clearly.
#include<stdio.h>
#include<conio.h>
#include <stdlib.h> //here
void input(int);
int *temp=0; //here
int d;
void main()
{
int x=0;
float avg=0,t=0;
printf("\nHow many days : ");
scanf("%d",&d);
temp=malloc(d * sizeof(int)); //here
input(d);
conv();
for(x=0;x<d;x++)
{
t=t+temp[x];
}
avg=t/d;
printf("Avarage is %f",avg);
getch();
}
void input(int d)
{
int x=0;
for(x=0;x<d;x++)
{
printf("Input temperature in Celsius for #%d day",x+1);
scanf("%d",&temp[x]);
}
}
void conv()
{
int x=0;
for(x=0;x<d;x++)
{
temp[x]=1.8*temp[x]+32;
}
}
Maybe it's late to answer but...
If you work with small embedded system you might not have malloc and free functions.
So you have to sacrifice memory for 366 * sizeof(your_type), define it statically and use as a circular buffer. Then you can always slice it by number of days you need to calculate an average value.
Of course this makes natural constrains. You can define it by yourself.

Programming with functions and structures using C, getting strange output, no errors

I'm learning a bit C and i'm doing an exercise where i use structures and functions to collect employee infos and just print them out.
I'm declaring the functions and the struct in the header since i need them in both of the other files.
//employee.h
int addEmployee(void);
int printEmployee(int i);
struct employeelist
{
char last [20];
char first[20];
int pnumber;
int salary;
};
The "core" file is executing the both functions. The first function asks for the number of employees and gives a value back for the second function where the information is collected and stored. There are no errors and i've checked the code several times.
//employee.c
#include "employee.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int numE;
int i;
int addEmployee(void)
{
struct employeelist employee[5];
int numE;
printf("How many employees do you want to add to the list?: ");
scanf("%d", &numE);
printf("Please type in the last name, the first name,\nthe personal number and the salary of your employees.\n");
for (i=0; i < numE; i++)
{
printf("Last name: ");
scanf("%s", employee[i].last);
printf("First name: ");
scanf("%s", employee[i].first);
printf("Personal number: ");
scanf("%d", &employee[i].pnumber);
printf("Salary: ");
scanf("%d", &employee[i].salary);
}
return numE;
}
int printEmployee(int emp)
{
struct employeelist employee[5];
for (i=0; i < emp; i++)
{
printf("Last name: {%s}\nFirst name: {%s}\nPersonal number: {%d}\nSalary: {%d}\n",employee[i].last,employee[i].first, employee[i].pnumber, employee[i].salary);
}
getchar();
getchar();
return emp;
}
The last file contains the main() function to execute the functions above.
#include "employee.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int emp;
int main ()
{
struct employeelist employee[5];
int emp = addEmployee();
printEmployee(emp);
return 0;
}
Now my problem is that everything works only the output is incorrect. I can't even say what it is. Some kind of random mix of signs, letters and numbers. Since i have no idea where my mistake is, i would be glad about any advise to solve this problem. Thank you.
I have added a screenshot of my output. Maybe it helps.
You're trying to use a local variable, which ceases to exist when the function returns.
int addEmployee(void)
{
struct employeelist employee[5];
/* ... */
}
The variable employee only exists inside the addEmployee() function; and it is a different object every time the function is called.
int printEmployee(int emp)
{
struct employeelist employee[5];
/* ... */
}
This employee has no relation to the one in addEmployee.
But don't do the easy thing now (*); do the right thing: declare the array in the main() function and pass it around.
//employee.h
struct employeelist
{
char last [20];
char first[20];
int pnumber;
int salary;
};
/* add up to `maxemp` employees to the array and
** return number of employees added */
int addEmployee(struct employeelist *, int maxemp);
/* print all employees from index 0 to (nemp - 1) */
int printEmployee(struct employeelist *, int nemp);
Declare an array in main(), and pass it around
#include "employee.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main ()
{
int emp;
struct employeelist employee[5];
int emp = addEmployee(employee, 5);
printEmployee(employee, emp);
return 0;
}
(*) Don't declare a global variable for employees
Edited employee.h and added a main() function
You have a brand new variable in your print function that isn't even initialized. So it contains only garbage and that is printed
The heart of the problem is that you're working with three different arrays of employees instead of the one array that you think you've got. Anything declared within a pair of curly braces in C only 'exists' while the program is executing code inside those braces. You've declared three different arrays of employee structs in three different blocks of code.
To point you in the right direction (irrespective of whether this is homework or self-study, this is a learning exercise so just fixing your code probably isn't what you want) you should think about how you can pass the same employee array to each of your functions in turn. (EDIT: pmg beat me to it.)
Declare the array once, in your main() function as you've already done, and modify your two functions printEmployee() and addEmployee() to take that array as a parameter instead of declaring their own local arrays.
Here is a very simple example using ints showing how parameters and return values work. You'll have to do some reading about pointers to extend this to your case.
int main() {
int number = 2;
int newNumber;
newNumber = timesTwo(number);
printf("number: %d newNumber: %d", number, newNumber);
}
int timesTwo(int param) {
return param * 2;
}
Before you start breaking things out into separate files and working with structs and pointers it is a good idea to practice the concepts of functions, parameters and variables by building simple programs in a single file.
You declare the employee array locally to both functions, so they cannot access each other's data.
The main issue, as others have already said, is that you are declaring a struct employeelist employee[5] in each of your functions. This makes those variables local to their functions and thus inaccessable from one function to the other. So, when printEmployee goes to print, the data it is printing is gibberish.
There are a few things needed to fix this:
Make one declaration of your employee list in your main (which you already have) and then pass that into the functions. You'll need to do the passing by means of the array name so that the functions will treat the array properly.
As a result of the above, you'll need to move the struct declaration to be above the function prototypes and then change the prototypes in employee.h to accomodate the passing of the employeelist.
You'll have to check that the user doesn't try to enter more records than your array has space for. Alternatively, you could just declare a pointer in the main and malloc() the needed memory in the addEmployee function.
A few other suggestions to make things a little easier on yourself:
Call your struct employee (or something like that) and your array employeelist (or something similar).
Use typedef on your struct to shorten & simplify your declarations.
Change your printEmployee to be a void function (i.e. void return type).
Take a look.. Well distribued and simple to read, it just needs a little improvement to become bigger and do the work u want.
typedef struct
{
char last [20];
char first[20];
long int pnumber;
int salary;
}employee;
/* the two functions clearly declared */
int addEmployee(employee const wEmployeeList[]);
void printEmployee( employee const wEmployeeList[], int );
int main()
{
int numberE;
employee employeeList[2];
numberE = addEmployee(employeeList);
printEmployee(employeeList, numberE);
return 0;
}
int addEmployee(employee const wEmployeeList[2]){
int i;
for (i=0; i < 2; i++)
{
printf("Last name: ");
scanf("%s", wEmployeeList[i].last);
printf("First name: ");
scanf("%s", wEmployeeList[i].first);
printf("Personal number: ");
scanf("%ld", &wEmployeeList[i].pnumber);
printf("Salary: ");
scanf("%d", &wEmployeeList[i].salary);
}
return 2;
}
void printEmployee(employee const wEmployeeList[2], int numberEmployee){
int i;
for (i=0; i < numberEmployee; i++)
{
printf("\n\nLast name: %s\nFirst name: %s\nPersonal number: {%ld}\nSalary: {%d}\n \n",wEmployeeList[i].last,wEmployeeList[i].first, wEmployeeList[i].pnumber, wEmployeeList[i].salary);
}
}

Resources