Why I can not set struct - c

Hello everyone I have a program that picks up some factors from the user
For the purpose of planning workers in the factory
1 ID
2 working hours
3 Wages
4 How many workers there are in the factory
The program ran and everything is fine but the program fails to print the requested values
For example for the value 2 employees, ID 23, 34
Wage hours etc. The program prints an ugly and large number and for the ID printed 2! And not 23 34
How do I fix the ID and everything?
I mention again the output looks like this!
**
**number of Factory workers
2
ID: 2
Hour lySal: -858993460
workdays: -858993460
salary: -858993460
worker day is: 2 worker hours is: -858993460
ID: 2
Hour lySal: -858993460
workdays: -858993460
salary: -858993460
worker day is: 2 worker hours is: -858993460
C:\Users\יובל\source\repos\lastpartproject\Debug\lastpartproject.exe (process 8488) exited with code 0.
To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.
Press any key to close this window . . .**
**
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int DayNumber; //1-31
int WorkHours; // 1-12
} WorkDay;
typedef struct {
long ID;//ת.ז.
int HourlySal; // שכר לשעה
int workdays; //מספר ימי עבודה של העובד בחודש הנוכחי
WorkDay* wd; // מצביע למערך דינאמי של נתוני ימי העבודה בחודש נוכחי
double salary; // סה"כ שכר עבודה של העובד בחודש נוכחי
} Worker;
Worker* InitFactory(int* pSize);
void PrintFactory(Worker* pWorker, int size);
void CalculateSalary(Worker* pWorker, int size);
void InputWorkDay(WorkDay* pWD);
void PrintWorkDay(WorkDay wd);
void InputWorker(Worker* pW);
void PrintWorker(Worker w);
int main() {
Worker* pFactory = NULL;
int size = 0;
pFactory = InitFactory(&size);
CalculateSalary(pFactory, size);
PrintFactory(pFactory, size);
// free memory -
}
void InputWorkDay(WorkDay* pWD)
{
printf("input worker day and worker hours\n");
scanf("%d %d", &(pWD->DayNumber), &(pWD->WorkHours));
}
void PrintWorkDay(WorkDay wd)
{
printf("worker day is: %d worker hours is: %d\n", wd.DayNumber, wd.WorkHours);
}
void InputWorker(Worker* pW)
{
printf("input ID\n");
scanf("%d", &(pW->ID));
printf("Hour lySal\n");
scanf("%d", &(pW->HourlySal));
printf("input workdays\n");
scanf("%d", &(pW->workdays));
printf("input salary\n");
scanf("%d", &(pW->salary));
InputWorkDay(pW->wd);
}
void PrintWorker(Worker w)
{
printf("ID: %d\n", w.ID);
printf("Hour lySal: %d\n", w.HourlySal);
printf("workdays: %d\n", w.workdays);
printf("salary: %d\n", w.salary);
PrintWorkDay(w.wd[0]);
}
Worker* InitFactory(int* pSize)
{
int number_student = 0;
Worker* Pfactory = NULL;
printf("number of Factory workers\n");
scanf("%d", &number_student);
*pSize = number_student;
Pfactory = (Worker*)malloc(*pSize * sizeof(Worker));
if (Pfactory == NULL)
{
printf("no storage\n");
exit(1);
}
for (int i = 0; i < *pSize; i++)
{
Pfactory[i].wd = (WorkDay*)malloc(31 * sizeof(WorkDay));
InputWorker(&Pfactory[i]);
}
}
void PrintFactory(Worker* pWorker, int size)
{
for (int i = 0; i < size; i++)
{
PrintWorker(*pWorker);
}
}
void CalculateSalary(Worker* pWorker, int size)
{
for (int j = 0; j < size; ++j)
{
//pWorker[j].HourlySal* pWorker[j].workdays;
}
}

At least these problem:
Assignment fails as InitFactory() does not return a value.
pFactory = InitFactory(&size);
Found this quickly by having many warnings enabled:
warning: control reaches end of non-void function [-Wreturn-type]
Save time, be more productive. Enable all warnings.
Other samples:
scanf("%d", &(pW->salary));
warning: format '%d' expects argument of type 'int', but argument 2 has type 'long int' [-Wformat=]
printf("salary: %d\n", w.salary);
warning: format '%d' expects argument of type 'int', but argument 2 has type 'double' [-Wformat=]
There are more like errors to find.

Related

Taking input and creating structs

I'm trying to take from stdin in a format like this
3
0 -1 1 -1 2
2 0 -1 -1 -1
2 -1 -1 0 -1
4
1 0
1 2
2 2
0 1
and create structs and fill in the states based on that information
Whenever I enter in these inputs it seems to stop whenever it sees a 0 or a 2
I have no idea whats causing this
Here is my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void getInput();
int getNrOfX();
int getCurrentRoom();
struct Room {
int state;
int northState;
int southState;
int eastState;
int westState;
};
struct Creature {
int type;
int location;
};
int main() {
//creates all the inital rooms and creatures
int nrOfRooms = getNrOfX();
struct Room rooms[nrOfRooms];
for(int i = 0; i < nrOfRooms; i++){ //creates rooms and stores them into the rooms array
scanf("%d %d %d %d %d", rooms[i].state, rooms[i].northState, rooms[i].southState, rooms[i].eastState, rooms[i].westState);
}
int nrOfCreatures = getNrOfX();
struct Creature creatures[nrOfCreatures];
for(int i = 0; i < nrOfCreatures; i++){ //creates creatures and stores them in the creatures array
scanf("%d %d", creatures[i].type, creatures[i].location);
}
//Gameplay loop
while (1) {
char input[30];
scanf("%s", input);
if(strcmp(strupr(input), "LOOK") == 0) {
int playerLocation = getCurrentRoom(nrOfRooms, &creatures);
printf("Room State %d\n", rooms[playerLocation].state);
printf("%d\n", rooms[playerLocation].northState);
break;
}
}
return 0;
}
int getNrOfX() {
int nrOfX;
scanf("%d", &nrOfX);
return nrOfX;
}
int getCurrentRoom(int nrOfRooms, struct Creature *creature) {
for(int i = 0; i < nrOfRooms; i++) {
if (creature[i].type == 0){
return creature[i].location;
}
}
}
The program compiles but when I enter the input
2 0 -1 -1 -1
ParserError:
Line |
1 | 2 0 -1 -1 -1
| ~
| Unexpected token '0' in expression or statement.
Please let me know what I can do
I have no idea whats causing this
Save time, enable all warnings
Enable the compiler to fully do its job.
format '%d' expects argument of type 'int *', but argument 6 has type 'int' [-Wformat=]
scanf("%d %d %d %d %d", rooms[i].state, rooms[i].northState, rooms[i].southState, rooms[i].eastState, rooms[i].westState);
With scanf(), "%d" matches an int *, not an int.
// scanf("%d %d %d %d %d", rooms[i].state, rooms[i].northState, rooms[i].southState, rooms[i].eastState, rooms[i].westState);
scanf("%d %d %d %d %d", &rooms[i].state, &rooms[i].northState,
&rooms[i].southState, &rooms[i].eastState, &rooms[i].westState);
Same for scanf("%d %d", creatures[i].type, creatures[i].location);.
In function 'getCurrentRoom':
:1: warning: control reaches end of non-void function [-Wreturn-type]
getCurrentRoom() does not always return a value.

How to validation struct value is exist or not using for loop in C language

i want to ask you, here in my code i used case condition for input, but i got a trouble, in my code i want to check is my "NIM" value was inputted to struct or not, if it was inputted, it can't be inputted to struct. Here are my code
#include <stdio.h>
#include <string.h>
struct data {
char nim[10];
};
struct data batas[100];
int a, b, c, d;
int i, j;
char x;
void inputdata()
{
printf("\nInput Data\n");
printf("=======================\n");
printf("NIM : "); scanf("%s", batas[a].nim);
for(i=0; i<a; i++){
if (strcmp(batas[a].nim, batas[i].nim) == 0) {
x = "FLAG";
} else {
x = "FLAGX";
}
}
printf("%s", x);
if (strcmp(x, "FLAGX") == 0) {
a++; // This will input to struct
}
}
void showdata()
{
j=0;
for(i=0; i<a; i++){
j = j + 1;
printf("\nData-%i", j);
printf("\nNIM : %s", batas[i].nim);
}
}
int main() {
int menu;
do {
printf("\n\Choose input = "); scanf("%d", &menu);
switch(menu)
{
case 1 : inputdata(); break;
case 2 : showdata(); break;
}
}while (menu != 3);
return 0;
}
From this i always get an error Segmentation Fault. I appreciate you guys, thank you.
You have already got many suggestion to check your program for warnings and errors.
Check warnings and errors of your program : https://onlinegdb.com/By1VeOK1d
main.c:20:9: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
main.c:22:9: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
main.c:25:12: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
main.c:26:14: warning: passing argument 1 of ‘strcmp’ makes pointer from integer without a cast [-Wint-conversion]
/usr/include/string.h:144:12: note: expected ‘const char *’ but argument is of type ‘char’
main.c:44:12: warning: unknown escape sequence: '\C'
All of the above warnings will be cleared just by making two changes to your code
line 11 change char x; as char* x;
line 44 change printf("\n\Choose input = "); as printf("\n Choose input = ");
Moving on to your code correctness, your function inputdata() is depending on global variable a and the loop for(i=0; i<a; i++){ is never true because i < a will never be true, since a is global (default value 0).
Which leads to execution of other statements in an undefined way.
you are directly reading your input into structure scanf("%s", batas[a].nim);, instead read into a local variable like char temp[30] , then add it your batas and continue checking for the existence of your string from next input.
#include <stdio.h>
#include <string.h>
struct data {
char nim[10];
};
struct data batas[100];
int a, b, c, d;
int i, j, flag;
void inputdata()
{
flag = 0;
printf("\nInput Data\n");
printf("=======================\n");
printf("NIM : ");
scanf("%s", batas[a].nim);
for(i=0; i<a; i++){
if (strcmp(batas[a].nim, batas[i].nim) == 0) {
flag = 1;
}
}
if (flag == 0) {
a++; // This will input to struct
}
}
void showdata()
{
j=0;
for(i=0; i<a; i++){
j = j + 1;
printf("\nData-%i", j);
printf("\nNIM : %s", batas[i].nim);
}
}
int main()
{
int menu;
do {
printf("\n\Choose input = "); scanf("%d", &menu);
switch(menu)
{
case 1 : inputdata(); break;
case 2 : showdata(); break;
}
}while (menu != 3);
return 0;
}

Program stops working after entering the value for more than 6 users

I have a school project which asks me to write a code using struct and functions, regarding sales in Greek cities. You are prompted to enter the values of 'em. The program works just fine if I enter that there's 6 salesmen, but a number larger than that makes it stop after entering all the values.. An example would be:
Number of salesmen: 7
(
Enter the his id:
Enter his surname:
Enter the number of sales:
Enter the area code:
) x7 times.
Then, when you enter the last value, it would just stop. Not exit, not stop responding/crash, literally just stop, and you would be unable to type anything more, only option would be to exit.
Thing is, there's no error or warning in both the build messages and the log, which has me quite confused.
My guess is that the error is in the function "calcSales" but I wanted to post the whole code just in case you need more info on it.
Could you take a look at the code and tell me if you find anything wrong? Thank you.
#include <stdio.h>
#include "genlib.h"
#include <simpio.h>
#include <string.h>
#define N 20
#define M 4
struct{
int id;
char surname[16];
long sales;
int area;
} salesmen[N];
void info(int *count);
void calcSales(int *count);
int main(){
int count;
printf("Give me the number of salesmen:\n");
count=GetInteger();
info(&count);
calcSales(&count);
}
void info(int *count){
for (int i=0; i<*count; i++){
printf("\nInfo for salesman number %d:\n", i+1);
printf("\nGive me his id: ");
salesmen[i].id=GetInteger();
printf("\nGive me his surname: ");
gets(salesmen[i].surname);
printf("\nGive me the number of sales: ");
salesmen[i].sales=GetLong();
printf("\n 1=Thessaloniki, 2= Athens, 3= Volos, 4= Hrakleio \n");
printf("\nLastly, give me the number of his area: ");
salesmen[i].area=GetInteger();
if (salesmen[i].area>4){
printf("\nThe number you are trying to enter doesn't match to an area.\n");
break;
}
}
}
void calcSales(int *count){
long tSales[4];
for (int i=0; i<*count; i++){
tSales[i]=0;
}
for (int i=0; i<*count; i++){
if(salesmen[i].area==1){
tSales[0]+=salesmen[i].sales;
}
if(salesmen[i].area==2){
tSales[1]+=salesmen[i].sales;
}
if(salesmen[i].area==3){
tSales[2]+=salesmen[i].sales;
}
if(salesmen[i].area==4){
tSales[3]+=salesmen[i].sales;
}
}
for (int i=0; i<4; i++){
printf("\nSales for area number %d: %ld\n",i+1, tSales[i]);
}
}
Your guess is correct. The mistake in calcSales function.
Exactly, the following part:
long tSales[4];
for (int i=0; i<*count; i++) {
tSales[i]=0;
}
The *count has value of 20. Which means the loop goes from i = 0 until i = 19.
When you access tSales[i] for i = 4 and above. You're invoking an undefined behavior. It's a memory that you didn't reserve for tSales. I suggest using the following:
long tSales[4];
for (int i=0; i<4; i++) {
tSales[i]=0;
}
Or better:
long tSales[4];
for (int i=0; i<sizeof(tSales)/sizeof(tSales[0]); i++) { // number of elements is the total size of array divided by the size of one element.
tSales[i]=0;
}
Or even better, you don't need a loop at all:
long tSales[4] = {0};
Besides your problem:
For the code you're providing, you don't need to pass a pointer to the functions.
You can make the code look as follows:
#include <stdio.h>
#include "genlib.h"
#include <simpio.h>
#include <string.h>
#define N 20
#define M 4
struct{
int id;
char surname[16];
long sales;
int area;
} salesmen[N];
void info(int count);
void calcSales(int count);
int main(){
printf("Give me the number of salesmen:\n");
int count=GetInteger(); // I've made declaration and assignment in same line. That seems cleaner to me.
info(count);
calcSales(count);
}
void info(int count){
for (int i=0; i<count; i++){
printf("\nInfo for salesman number %d:\n", i+1);
printf("\nGive me his id: ");
salesmen[i].id=GetInteger();
printf("\nGive me his surname: ");
gets(salesmen[i].surname);
printf("\nGive me the number of sales: ");
salesmen[i].sales=GetLong();
printf("\n 1=Thessaloniki, 2= Athens, 3= Volos, 4= Hrakleio \n");
printf("\nLastly, give me the number of his area: ");
salesmen[i].area=GetInteger();
if (salesmen[i].area>4 || salesmen[i].area < 1){ // Added an extra condition.
printf("\nThe number you are trying to enter doesn't match to an area.\n");
break;
}
}
}
void calcSales(int count){
long tSales[4] = {0};
for (int i=0; i<count; i++){
tSales[salesmen[i].area - 1]+=salesmen[i].sales; // No need for if conditions.
}
for (int i=0; i<4; i++){
printf("\nSales for area number %d: %ld\n",i+1, tSales[i]);
}
}

updating string array inside a function in C

I define a string array in main function, and I want to update it inside another function as follows:
#include <stdio.h>
#define SIZE 15
void read_arrays(char *competitors[SIZE], float points[SIZE], int numOfCompetitors)
{
for (int cntr = 0; cntr < numOfCompetitors; cntr++)
{
printf("Enter the name of competitor %d", cntr+1);
scanf("%s", &*competitors[cntr]);
printf("Enter the point of competitor %d", cntr+1);
scanf("%f", &points[cntr]);
}
}
int main()
{
char *competitors[SIZE];
float points[SIZE];
int numOfCompetitors = 0;
while (numOfCompetitors > 15 || numOfCompetitors < 1)
{
printf("Enter the number of competitors: ");
scanf("%d", &numOfCompetitors);
if (numOfCompetitors > 15) printf("Number of competitors cannot be more than 15!\n");
}
read_arrays(&*competitors[SIZE], &points[SIZE], numOfCompetitors);
printf("%f", points[0]);
}
But I get the following error:
cc homework2.c -o homework2
homework2.c: In function ‘main’:
homework2.c:28:14: warning: passing argument 1 of ‘read_arrays’ from incompatible pointer type [-Wincompatible-pointer-types]
read_arrays(&*competitors[SIZE], &points[SIZE], numOfCompetitors);
^
homework2.c:5:6: note: expected ‘char **’ but argument is of type ‘char *’
void read_arrays(char *competitors[SIZE], float points[SIZE], int numOfCompetitors)
I want to assign the values in array of strings with scanf in a loop. How I can manage to do that?
You can just use the name of the variable when you pass it to the function, you also need to specify the size of the char matrix (~ array of strings).
So this: read_arrays(&*competitors[SIZE], &points[SIZE], numOfCompetitors);
Becomes: read_arrays(competitors, points, numOfCompetitors);
Full code:
#include <stdio.h>
#define SIZE 15
void read_arrays(char competitors[SIZE][30], float points[SIZE], int numOfCompetitors)
{
for (int cntr = 0; cntr < numOfCompetitors; cntr++)
{
printf("Enter the name of competitor %d", cntr+1);
// We read up to 29 characters => no overflow as the size is up to 30
scanf("%29s", competitors[cntr]);
printf("Enter the point of competitor %d", cntr+1);
scanf("%f", &points[cntr]);
}
}
int main()
{
char competitors[SIZE][30];
float points[SIZE];
int numOfCompetitors = 0;
while (numOfCompetitors > 15 || numOfCompetitors < 1)
{
printf("Enter the number of competitors: ");
scanf("%d", &numOfCompetitors);
if (numOfCompetitors > 15) printf("Number of competitors cannot be more than 15!\n");
}
read_arrays(competitors, points, numOfCompetitors);
printf("%s", competitors[0]);
printf("%s", competitors[1]);
printf("%f", points[0]);
}
As an alternative to Daniel Illescas you could just allocate space for each competitor that you input. Just be sure to free them later.
#include <stdio.h>
#define SIZE 15
void read_arrays(char *competitors[SIZE], float points[SIZE], int numOfCompetitors)
{
for (int cntr = 0; cntr < numOfCompetitors; cntr++)
{
competitors[cntr] = (char*)calloc(1, 32);
printf("Enter the name of competitor %d", cntr + 1);
scanf("%s", competitors[cntr]);
printf("Enter the point of competitor %d", cntr + 1);
scanf("%f", &points[cntr]);
}
}
int main()
{
char *competitors[SIZE];
float points[SIZE];
int numOfCompetitors = 0;
while (numOfCompetitors > 15 || numOfCompetitors < 1)
{
printf("Enter the number of competitors: ");
scanf("%d", &numOfCompetitors);
if (numOfCompetitors > 15) printf("Number of competitors cannot be more than 15!\n");
}
read_arrays(competitors, points, numOfCompetitors);
printf("%f", points[0]);
}

C asking for user txt file, saving in array, and outputting in txt

So I have a function built already that calculated 25 random temperatures and outputted them and had a max, min, and average feature. I'm now trying to incorporate input files and output files via txt.
I tried to do some research and plug in what I could (even if I barely understood it), can someone lend some light on my code?
int get_value(void);
void calc_results(void);
void read_temps(void);
int sum = 0;
int min = 0;
int max = 0;
int temp[25];
int i = 0; //For array loop
int j = 0; //For printf loop
float avg = 0;
void read_temps() {
char fname[128];
printf("Enter .txt file name \n");
scanf("%123s", fname);
strcat(fname, ".txt");
FILE *inputf;
inputf=fopen(fname, "w");
for (i = 0; i < 25; i++){
temp[i] = fname;
sum += temp[i];
}
}
int main () {
calc_results();
return 0;
};
void calc_results(void) {
FILE * fp;
fp = fopen("Output_temps.txt", "w+");
avg = ((sum)/(25));
max = temp[0];
for(i=1;i<25;i++){
if(max<temp[i])
max=temp[i];
};
min =temp[0];
for(i=1;i<25;i++){
if(min>temp[i])
min=temp[i];
};
fprintf("Temperature Conditions on October 9, 2015 : \n");
fprintf("Time of day Temperature in degrees F \n");
for(j=0;j<25;j++){
fprintf(" %d %d\n",j,temp[j]);
}
fprintf("Maximum Temperature for the day: %d Degrees F\n", max);
fprintf("Minimum Temperature for the day: %d Degrees F\n", min);
fprintf("Average Temperature for the day: %.1f Degrees F\n", avg);
fclose(fp);
};
There were a few errors in your code, the most critical one being it doesn't compile. If you're having issues you'll want to follow the instructions for how to make a ssce. You will get a much better response this way. Then explain clearly the specific issue you are having and what it is that is happening or not happening as opposed to what you expect.
With your code you seem to be assigning to your temp array the fname variable instead of reading in the int data from the user file.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// assuming you want a maximum of temperatures of 25
#define TEMP_NUMBER 25
// use a struct to maintain and the temparatur data in one place
// without resorting to using global variables or having functions
// that require numerous parameters.
struct temp_data {
char fname[128];
int max;
int min;
int sum;
int temps[TEMP_NUMBER];
float avg;
};
struct temp_data *temps_init(void)
{
// creates a pointer to struct temp_data to hold
// your various temparture related fields
struct temp_data *td = malloc(sizeof *td);
td->sum = 0;
td->avg = 0.0;
return td;
}
void read_temps(struct temp_data *td)
{
// in your sample code you have this set to "w", needs to be "r"
FILE *inputf = fopen(td->fname, "r");
// handle error
if (!inputf) {
perror("fopen");
exit(0);
}
for (int i = 0; i < TEMP_NUMBER; i++) {
// you were setting fname to the temparature array
// instead you need to scan the temp file
fscanf(inputf, "%d", &(td->temps[i]));
td->sum += td->temps[i];
}
}
void print_results(struct temp_data *td)
{
// a print function to separate logic
FILE *fp = fopen("Output_temps.txt", "w+");
if (!fp) {
perror("fopen");
exit(0);
}
fprintf(fp, "Temperature Conditions on October 9, 2015 : \n");
fprintf(fp, "Time of day Temperature in degrees F \n");
for(int i=0; i < TEMP_NUMBER; i++)
fprintf(fp, " %d %d\n", i, td->temps[i]);
fprintf(fp, "Maximum Temperature for the day: %d Degrees F\n", td->max);
fprintf(fp, "Minimum Temperature for the day: %d Degrees F\n", td->min);
fprintf(fp, "Average Temperature for the day: %.1f Degrees F\n", td->avg);
fclose(fp);
}
void calc_results(struct temp_data *td)
{
// do only calculations
td->avg = td->sum / TEMP_NUMBER;
td->min = td->temps[0];
td->max = td->temps[0];
for (int i=1; i < TEMP_NUMBER; i++) {
td->min = td->temps[i] < td->min ? td->temps[i] : td->min;
td->max = td->temps[i] > td->max ? td->temps[i] : td->max;
}
}
int main(int argc, char *argv[])
{
// Moved user input into the main() from read_temps()
// now read_temps() only needs to read and record the temp data
struct temp_data *td = temps_init();
printf("Enter .txt file name \n");
scanf("%123s", td->fname);
strcat(td->fname, ".txt");
read_temps(td);
calc_results(td);
print_results(td);
free(td);
return 0;
};
Using a file called sample.txt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

Resources