uninitialized variable in function - c

for the function below i have to sort an array of employees by age in descending order and need the size but cant put it in the function variables, my teacher told me to compute the size by doing this in main but for the loop with j in it it tells me elementSize may be used unitialized in this function. In main it says the int elementSize = " " elementSize is an unused variable.
int elementSize = sizeof(employeeList)/sizeof(Employee);//getting the size of the list
main
#include "lab10.h"
int main() {
Employee employeeList[10000];
readfile(employeeList);
clock_t start,end;
double cpu_time_used;
start = clock();
int elementSize = sizeof(employeeList)/sizeof(Employee);//getting the size of the list
bubbleSort(employeeList);//call bubble sort function to sort list in descending order
printList(employeeList, 25);
end = clock();
cpu_time_used = (double)(end-start)/CLOCKS_PER_SEC*1000;
printf("Time used to compute sorting was %f ms.\n",cpu_time_used);
int bin30=binSearch(employeeList, 0, 9999, 30);//binary search for people of the age of 30
if(bin30== -1){
printf("employees not found!\n");//if employee of age 30 arent found
} else {
printf("%s %s %d %d\n", employeeList[bin30].fname, employeeList[bin30].lname, employeeList[bin30].age, employeeList[bin30].salary); //print out employees info
printf("element present at index %d", bin30);
printf("time used is %f ms\n\n",cpu_time_used);//record time
}
int bin130=binSearch(employeeList, 0, 9999, 130);//binary search for people of the age of 30
if(bin130== -1){
printf("employees not found!\n");//if employee of age 130 arent found
} else {
printf("%s %s %d %d\n", employeeList[bin130].fname, employeeList[bin130].lname, employeeList[bin130].age, employeeList[bin130].salary); //print out employees info
printf("element present at index %d", bin130);
printf("time used is %f ms\n\n",cpu_time_used);//record time
}
return 0;
}
void bubbleSort(Employee employeeList[]) {
int swap;
int i=0;
int j=0;
for(i=0; elementSize > i; i++) {//for loop to sort
for(j=0; elementSize > j ;j++) {
if(employeeList[j+1].age > employeeList[j].age) {//comparing the two values
swap = employeeList[j].age;//swapping the temp variable with the employee
employeeList[j].age= employeeList[j+1].age;//setting the lower employeee to [j]
employeeList[j+1].age = swap;//setting the higher employee to [j+1]
}//end of if statement
}//end of second for loop
}//end of first for loop
}
#include "lab10.h"
//This function reads from a file and creates an array of Employee structure containing their information.
void readfile(Employee employeeList[]){
FILE *fp;
fp = fopen("employeeData.csv", "r");
int i = 0;
if (fp) {
while (i<10000){
fscanf(fp, "%[^,],%[^,],%d,%d\n",employeeList[i].fname,employeeList[i].lname,&employeeList[i].age,&employeeList[i].salary);
i++;
}
}
fclose(fp);
}
void printList(Employee employeeList[], int size)
{
int i=0;
for(i=0; i<size; i++)//going through the first 25 elements of the array
{
printf("%d ", employeeList[i].age);//printing off the elements
}
}
int binSearch(Employee employeeList[], int first, int last, int age)
{
if(first > last){
return -1;//base case
}
int mid= (first + last)/2;//finding middle of the array
if(age > employeeList[mid].age)
return binSearch(employeeList, mid+1, last, age);//searching for high in
binary search through recursion
else if(age < employeeList[mid].age)
return binSearch(employeeList, first, mid-1, age);//searching for low in binary search through recursion
else
return mid;//return the expected value
}

You actually have two variables named elementSize in this code, one global and one local to bubbleSort. The local variable is shadowing the global variable, meaning that the global is not visible. Only the local is visible, and that local was never initialized.
Remove the local elementSize variable and the global one will become visible and will be used.

Related

segmentation fault (core dumped) gcc ubuntu

I was trying to make a simple function to make a group of number that user enters them, using pointer of pointer but i keep getting this error and its hard to tell where the problem is, if there any other option to use something else that tells me where the problem is instead of this weird error.
#include <stdio.h>
void BuildGroub(int** group,int* count){
int i=0;
int j;
printf("Enter the size of the group \n");
scanf("%d", &*count);
while(*count != 0){
printf("Enter the %d number of the group:\n", i);
j=0;
scanf("%d", &**(group+i));
while(**(group+i)!=**(group+j)){
j++;
}
if(j==i){
i++;
count--;
} else{
printf("you have already entered this number please try again: \n");
}
}
}
int main(){
int count;
int group[100];
int *groupptr = &group;
BuildGroub(&groupptr,&count);
for(int i=0;i<count;i++){
printf("%d, ", group[i]);
}
return 0;
}
With this question, you do not need to use double pointer. If you want to learn how to use the double pointer, you can google then there are a ton of examples for you, for example, Double Pointer (Pointer to Pointer) in C.
In BuildGroub you decrease the count pointer
if(j==i){
i++;
count--;
}
, but in the condition of while loop, you compare the value that count pointer points to. it seems strange.
while(*count != 0)
Even if you change count-- to (*count)--, it will decrease the number of elements that you enter to 0 when you get out of the while loop, then in main function:
for(int i=0;i<count;i++){} // count is equal to 0 after calling BuildGroub function if you use (*count--) in while loop.
You should use a temp value for while loop function, for example:
int size = *count;
while(size != 0){
...
if (i == j) {
i++;
size--;
}
}
You should use, for example, group[i] instead of *(group+i). It will be easier to read your code.
The code complete:
#include <stdio.h>
void BuildGroub(int* group,int* count){
int i=0;
int j;
printf("Enter the size of the group \n");
scanf("%d", count);
int size = *count;
while(size != 0){
printf("Enter the %d_th number of the group:\n", i);
j=0;
scanf("%d", &group[i]);
while(group[i] != group[j]) {
j++;
}
if(j==i){
i++;
size--;
} else{
printf("you have already entered this number please try again: \n");
}
}
}
int main(){
int count;
int group[100];
int *groupptr = group;
BuildGroub(groupptr,&count);
for(int i=0;i<count;i++){
printf("%d, ", group[i]);
}
return 0;
}
The test:
./test
Enter the size of the group
5
Enter the 0_th number of the group:
1
Enter the 1_th number of the group:
2
Enter the 2_th number of the group:
2
you have already entered this number please try again:
Enter the 2_th number of the group:
3
Enter the 3_th number of the group:
3
you have already entered this number please try again:
Enter the 3_th number of the group:
4
Enter the 4_th number of the group:
5
1, 2, 3, 4, 5,
If you want to use a double pointer, you need to change your function like this:
void BuildGroub(int** group, int* count) {
int i = 0;
int j;
printf("Enter the size of the group \n");
scanf("%d", &*count); //I think this is redundant but works.
while (*count != 0) {
printf("Enter the %d number of the group:\n", i);
j = 0;
scanf("%d", (*group + i)); //The content of group + i
while ( *( *group + i) != *(*group + j)) { //the content of the content
j++;
}
if (j == i) {
i++;
(*count)--; //The content decrement
} else {
printf("you have already entered this number please try again: \n");
}
}
}
But you have a big problem in main and it is because you are using the parameter count to decrement until zero inside the function. So when the function finish, count value is zero and you don't print anything... You need to change this, using a internal variable to make the count, and finaly, setting the parameter to be using in main.

Passing struct array to function and calculating average in C?

Beginner here, I've been trying this for hours and can't get it to work, searched online too and couldn't find an answer.
I'm trying to write a program where you input people by putting their age and height then calculate the average of each, and the average ratio of age to height. Whenever I pass the struct to my getAverage function, it returns the address (I think) instead of the averages.
#include <stdio.h>
#include <stdlib.h>
typedef struct person
{
int age;
double height;
} Person;
double getAv (Person people[50], int max)
{
int i;
double total, retval;
total = 0;
for (i=0; i<=max; i++)
{
total = total + people[i].age;
}
retval = total / max;
return retval;
}
int main (void)
{
Person people[50];
int i;
while (i++, people[i].age>=0)
{
printf ("Person #%d\n", i);
printf ("enter an age: ");
scanf ("%d", &people[i].age);
if (people[i].age<0)
break;
printf ("enter a height: ");
scanf ("%lf", &people[i].height);
printf ("\n");
}
double averageAge;
averageAge = getAv (&people[50], i);
printf ("%.1lf\n", averageAge);
}
Haven't implemented average height or ratio yet, just trying to get average of ages to work for now. When I try taking the & out of averageAge = getAv(&people[50], I); I get a compile error that tells me it needs the &. Any help would be appreciated.
There are serveral issues in you code, the first one:
Person people[50];
int i;
while (i++, people[i].age>=0)
You are using i uninitialized, thus, incrementing a variable containing garbage (or 0 as intended, but it is impossible to guarantee)
To avoid such problems in the future enable warnings on your compiler, the compiler would have told you something like:
ā€˜iā€™ is used uninitialized in this function [-Wuninitialized]
So switch to
Person people[50] = {0};
int i = 0;
It seems (based on the pre-increment operator ++i) that you want to use arrays with base 1, there is nothing wrong with that, but in your average function you are starting from 0, so use a for:
for (i = 0; ; i++)
{
...
if (people[i].age <= 0) break;
...
}
Another issue:
double averageAge;
averageAge = getAv (&people[50], i);
In this way you are passing only element 50 which is not part of your array (remember arrays are base 0 in C), to pass the entire array:
averageAge = getAv (people, i);
or
averageAge = getAv (&people[0], i);
The last one:
for (i=0; i<=max; i++)
You are including the element discarded when you was checking for age > 0, switch to:
for (i=0; i<max; i++)
A minor issue:
Iif the user enters 0 for the first element of people you end up dividing by 0
double averageAge;
averageAge = getAv (&people[50], i);
printf ("%.1lf\n", averageAge);
should be
if (i > 0)
{
double averageAge;
averageAge = getAv (people, i);
printf ("%.1f\n", averageAge); // No need to use lf (long double)
}
If you do it this way, you need to receive in your function (Person& people[], int n)
Where n is the length of the array.
We use the '&' to not do copies of the array and also you are passing only the element with index 50 in the function, simply do only (people, n)
there are mistakes in this code ,first you should initialize int i to int i=0 in mian function.
how are using this condition while (i++, people[i].age>=0) when you haven't scanned any input it's like using an uninitialized variable. you need a do-while like this
do
{
printf("Person #%d\n", i);
printf("enter an age: ");
scanf("%d", &people[i].age);
if (people[i].age < 0)
break;
printf("enter a height: ");
scanf("%lf", &people[i].height);
printf("\n");
i++;
} while (people[i-1].age >= 0);
also you are sending wrong arguments to your getAv function you should use averageAge = getAv (people, i);.
and in your function you have to remove = in this loop for (i=0; i<=max; i++) .this should be for (i=0; i<max; i++) ,otherwise the negative entered age will also be add to total and will affect the average.

I'm trying to get the counter to work, how many months have a higher income than the same month from last year

The line of code I'm having trouble with has to do with counting a number of months, I'm passing a value up from a function that I thought would work but I'm not getting a proper readout from it. I'm sure I'm missing something stupid or the mistake I made is very basic but I can't seem to get it right. I would greatly appreciate any help I can get. please excuse the many printf statements, I was trying to find where the error was.
#include <stdio.h>
#include <stdlib.h>
void DisplayInstructions();//function 1
void HigherSales(float yearOne, float yearTwo, int k);//fuction 2
int months (float yearOne, float yearTwo);//function 3
void main()
{
float yearOne[12];//variables
float yearTwo[12];
int i = 0;
int j = 0;
int k = 0;
int count = 0;
DisplayInstructions();//calling first function
printf(" \n");
for (i = 0; i<12; i++)//scanf for entering sales values
{
j= i+1;
printf("enter the sales figures for month %d in year one \n",j);
scanf_s("%f",&yearOne[i]);
}
for (i = 0; i<12; i++)
{
j= i+1;
printf("enter the sales figures for month %d in year two \n",j);
scanf_s("%f",&yearTwo[i]);
} //end of entering sales
k=0;
for (i = 0; i<12; i++)//populating function 2
{
k++;
HigherSales(yearOne[i], yearTwo[i], k);
}
printf("\n count before going into the for loop is %d \n",count);
for (i = 0; i<12; i++)
{
months(yearOne[i], yearTwo[i]);//populating function 3
printf("before going into count calculation months is reading %f",months(yearOne[12], yearTwo[12]));
count = count + months(yearOne[12], yearTwo[12]); //calling function 3 so that i get the sum of times y1 < y2
printf(" \n after calc count is %d \n after calc monts is returning %f", count, months(yearOne[12], yearTwo[12]));
}
printf(" \n the number of months in year two where sales have increased is %d \n", count);
system("pause");
}
void DisplayInstructions() //function 1 printf's
{
printf("\n");
printf("this program consists of one function called 'DisplayInstructions' \n");
printf("the function takes no arguments and simply dispays this message \n");
printf("it is innitalised above main, called inside main and described below main \n");
}
void HigherSales(float yOne, float yTwo, int g)
{
if(yOne < yTwo) //function 2 comparing logic
{
printf("month %d in year two had higher sales than the same month the year prior \n", g);
}
}
int months(float monthOne, float monthTwo)
{
int m = 0;
if(monthOne < monthTwo )
{
m = m + 1;
printf("\n in the mothhs function, m loop, m is %d \n", m);
return m;
}
}
The function int months(float monthOne, float monthTwo) does not work as you probably expect.
With int m = 0; the variable m always is initialized with 0 every time this function is called, therefore m = m + 1 won't count up how often the condition is true - its either 0 or 1
To make the function remember the value of m from its last call you need to declare it static int m = 0;
But in your case this wouldn't be the best idea either because you would only want to know the last return value (when all months are iterated).
Furthermore function months only has a return value if the condition is true - your compiler should have complained about that.
So if you want to make this simple comparison within a function which is called within a loop:
int months(float monthOne, float monthTwo)
{
if (monthOne < monthTwo)
return 1;
else
return 0;
}
for (i = 0; i<12; i++)
{
count += months(yearOne[i], yearTwo[i]);
}
In your context I cant figure out the purpose of count = count + months(yearOne[12], yearTwo[12]); - beside the fact that you are accessing the 13th element of your array which is invalid, it makes no sense to increment your counter by the same comparison every loop.
The modified code below addresses the errors I commented under your post as well as some others (see comments in code.) I automated inputs using rand() to speed up testing, but left all your original code. Comment out the auto populate sections for your purposes.
Note: Not all logic errors are addressed, but enough to get you started. Read the comments left in the code.:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
void DisplayInstructions();//function 1
void HigherSales(float yearOne, float yearTwo, int k);//fuction 2
int months (float yearOne, float yearTwo);//function 3
const char month[][4] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
void main()
{
float yearOne[12];//variables
float yearTwo[12];
int i = 0;
int j = 0;
int k = 0;
int count = 0;
srand(clock());//seed pseudo random number generator
DisplayInstructions();//calling first function
printf(" \n");
for (i = 0; i<12; i++)//scanf for entering sales values
{
j= i+1;
printf("enter the sales figures for month %d in year one \n",j);
yearOne[i] = rand();//Added to automate populating monthly sales numbers...
while(yearOne[i] < 500)
{
yearOne[i] = rand()%10000;//Added to automate populating monthly sales numbers...
Sleep(100);//pause execution for 0.1 seconds
}
printf("YearOne - %s: %lf\n", month[i], yearOne[i]);
//scanf("%f",&yearOne[i]);
}
for (i = 0; i<12; i++)
{
j= i+1;
printf("enter the sales figures for month %d in year two \n",j);
yearTwo[i] = rand();//Added to automate populating monthly sales numbers...
while(yearTwo[i] < 500)
{
yearOne[i] = rand()%10000;//Added to automate populating monthly sales numbers...
Sleep(100);//pause execution for 0.1 seconds
}
printf("YearTwo - %s: %lf\n", month[i], yearOne[i]);
//scanf("%f",&yearTwo[i]);
} //end of entering sales
k=0;
for (i = 0; i<12; i++)//populating function 2
{
k++;
HigherSales(yearOne[i], yearTwo[i], k);
}
printf("\n count before going into the for loop is %d \n",count);
for (i = 0; i<12; i++)
{ //Hint: In this for loop, you are calling months function more
//than you want to. Consider assigning a variable to read it's
//output, then use that variable in the printf statements.
months(yearOne[i], yearTwo[i]);//populating function 3
// printf("before going into count calculation months is reading %f",months(yearOne[i], yearTwo[i]));
printf("before going into count calculation months is reading %d",months(yearOne[i], yearTwo[i]));//changed format type to match variable type
count = count + months(yearOne[i], yearTwo[i]); //calling function 3 so that i get the sum of times y1 < y2
//printf(" \n after calc count is %d \n after calc monts is returning %f", count, months(yearOne[i], yearTwo[i]));
printf(" \n after calc count is %d \n after calc monts is returning %d", count, months(yearOne[i], yearTwo[i]));//changed format type to match variable type
}
printf(" \n the number of months in year two where sales have increased is %d \n", count);
// system("pause");
printf("hit any key to continue.");
getchar(); //this method is more idomatic and portable to pause code
}
void DisplayInstructions() //function 1 printf's
{
printf("\n");
printf("this program consists of one function called 'DisplayInstructions' \n");
printf("the function takes no arguments and simply dispays this message \n");
printf("it is innitalised above main, called inside main and described below main \n");
}
void HigherSales(float yOne, float yTwo, int g)
{
if(yOne < yTwo) //function 2 comparing logic
{
printf("month %d in year two had higher sales than the same month the year prior \n", g);
}
}
int months(float monthOne, float monthTwo)
{
static int m = 0;//use static here to allow m to keep value from call to call.
//static extends life of variable until program ends.
if(monthOne < monthTwo )
{
m = m + 1;
printf("\n in the mothhs function, m loop, m is %d \n", m);
}
return m;//moved from inside loop, otherwise return will not occur
//for some evaluations.
//Perhaps you would prefer an else statement
}

Reading a file in C and store data in arrays

My code below reads a file in C.It displays the file, the average score, maximum score,and the names of all the students who earned the maximum score. The exam scores(0-100 format to 1 decimal place and use a field width of columns) are stored in an array and the names(name and last name limited to 15 characters) are stored in a 2-dimensional array of characters that is parallel to the scores array. My problems are:
1) The code doesn't read(print) the file properly (I think is related to fscanf and the arrays).
2) My two functions don't print the results.
Any suggestion is appreciated, thanks.
#include "tools.h"
#define MAX 30 // Maximum number of students
int computeMax(double stSco[], int numSt); // Gets the average and highest
// score
void outputBest(double num[], char nameHg[][15], int hgPl, int totStu);
int main()
{
double score[MAX];
char name[MAX][15];
char fileName[80];
int k, count = 0, hgCt;
stream dataFile;
banner();
printf("Type the name of file you want to read\n");
scanf("%79[^/n]", fileName);
dataFile = fopen(fileName, "r");
if (dataFile == NULL)
{
fatal("Cannot open %s for input", fileName);
}
while (!feof(dataFile))
{
fscanf(dataFile, "(%lg,%s)", &score[k], &name[k]);
printf("%6.1f %s\n", score[k], name[k]);
count++; // It counts how many students there are
}
hgCt = computeMax(score, count); // Stores the value sent by the
// function
outputBest(score, name, hgCt, count);
fclose(dataFile);
bye();
return 0;
}
int computeMax(double stSco[], int numSt)
{
int k, maxScore = 0, sum = 0;
double maximum = 0, average = 0;
for (k = 0; k < numSt; k++)
{
sum += stSco[k]; // It sums all scores
if (stSco[k] > maximum)
{
maximum = stSco[k];
maxScore = k; // Stores the index of the maximum score
}
}
average = sum / numSt;
printf("The average score is %d\n", average);
printf("The maximum score is %d\n", maximum);
return maxScore;
}
void outputBest(double num[], char nameHg[][15], int hgPl, int totStu)
{
int k;
for (k = 0; k < totStu; k++)
{
if (num[k] = hgPl)
{ // It finds who has the highest score
printf("%s got the highest score\n", nameHg[k]);
}
}
}
First: scanf("%79[^/n]",fileName); should be scanf("%79[^\n]",fileName);, better to use fgets().
Second typo mistake: misspelled == by = in if() condition
if(num[k]=hgPl){ //It finds who has the highest score
// ^ = wrong
should be:
if(num[k] == hgPl){ //It finds who has the highest score
Edit:
Error in while loop..
fscanf(dataFile, "(%lg,%s)", &score[k], &name[k]);
// ^ ^ ^ remove ^
should be:
fscanf(dataFile, "%lg%14s", &score[k], name[k]);
and increment k in while loop. after printf("%6.1f %s\n", score[k], name[k]);.

How to print integers in typing order in C - increasing, decreasing or evenly

I have a problem with a c program I'm trying to write. The program must store integers in array (read from the keyboard). The numbers must be printed out in the order of entering, for example if you enter: 3 2 0 5 5 5 8 9, the ouput should be:
3 2 0 - decreasing
5 5 5 - evenly
8 9 - increasing
The problem for me is, that I can't write an algorithm which to be able to work in all cases.
I was trying to "flag" the elements with another array(using the same index, to save for each integer a value 1-for increasing, -1-for decreasing and 0 for evenly), but this works partly.
Have you any other ideas?
Thanks in advance :)
#include <stdio.h>
#include <stdlib.h>
main() {
int array[100];
int flag[100];
int num, i;
printf("Enter how many numbers you want to type: ");
scanf("%d",&num);
for(i=0;i<num;i++) {
scanf("%d",&array[i]);
}
for(i=0;i<num;i++){
if((array[i]<array[i+1])) {
flag[i]=flag[i+1]=1;
}
if(array[i]>array[i+1]) {
flag[i]=flag[i+1]=-1;
}
}
for(i=0;i<num;i++) {
if(array[i]==array[i+1]) {
flag[i]=flag[i+1]=0;
}
}
for(i=0;i<num;i++){
printf("%d ",flag[i]);
}
printf("\n");
for(i=0;i<num;i++) {
if(flag[i]==1) {
do{
if(flag[i]==1){
printf("%d ",array[i]);
i++;
}
}while(flag[i]==1);
printf(" - increasing\n");
}
if(flag[i]==0) {
do{
if(flag[i]==0){
printf("%d ",array[i]);
i++;
}
}while(flag[i]==0);
printf(" - evenly\n");
}
if(flag[i]==-1) {
do{
if(flag[i]==-1) {
printf("%d ",array[i]);
i++;
}
}while(flag[i]==-1);
printf(" - decreasing\n");
}
}
system("pause");
return 0;
}
Thoughts:
You only know if the 'first' number belongs to a descending, even, or ascending sequence after you see the 'second' number.
The 'third' number either belongs to the same sequence as the first two or is the 'first' number of another sequence.
So: check two numbers and assign a sequence type.
Keep checking numbers in the same sequence.
When you cannot assign the same sequence go back to checking two numbers and assigning a sequence.
Something like
int *n1, *n2, *n3;
n1 = <first element>;
n2 = n1 + 1;
n3 = n2 + 1;
/* some kind of loop */
if ((n3 - n2) HAS_SOME_SIGN_AS (n2 - n1)) /* n3 belongs to the sequence */;
n1++;
n2++;
n3++;
/* end loop */
#include <stdio.h>
int status(a, b){
if(a < b) return 1;
if(a > b) return -1;
return 0;
}
int main() {
int array[100]={0};
int old_status, new_status;
int old_pos;
int num, i, j;
const char* status_message[] = {"decreasing","evenly","increasing", "i don't know"};
printf("Enter how many numbers you want to type: ");
scanf("%d",&num);
for(i=0;i<num;i++)
scanf("%d",&array[i]);
//{num | 1 < num <= 100}
old_status =status(array[0], array[1]);
old_pos = 0;
for(i=1;i<num;++i){
new_status = status(array[i-1], array[i]);
if(old_status != new_status){
for(j=old_pos;j<i;++j)
printf("%d ", array[j]);
printf("- %s\n", status_message[1 + old_status]);
old_status = (i<num-1)? status(array[i], array[i+1]):2;
old_pos = i;
}
}
if(old_pos < num){ //not output section output
for(j=old_pos;j<i;++j)
printf("%d ", array[j]);
printf("- %s\n", status_message[1 + old_status]);
}
return 0;
}

Resources