How to display an index in a array with a function - c

I am trying to display the lowest price index in the array that is found through my function. But I am struggling to figure out how to make it display the specific index. Where do I need to pass the index variable in order to make display the lowest index with my display function?
#define COLOR_SIZE 50
#define PLANT_ARRAY_SIZE 3
struct Plant
{
int plantID;
double price;
char color[COLOR_SIZE];
};
int main()
{
int index;
//create array
struct Plant totalPlants[PLANT_ARRAY_SIZE];
//initialize array
for (int count = 0; count < PLANT_ARRAY_SIZE; count++)
{
initializePlant(totalPlants);
}
// find lowest
index = findCheapestPlant(totalPlants, PLANT_ARRAY_SIZE);
//display lowest cost plant
displayPlant(totalPlants[index]);
return 0;
}
void initializePlant(struct Plant *x)
{
printf("\nEnter the information for the next plant\n");
printf("Enter plant ID as an integer>");
scanf("%d", &(x->plantID));
printf("Enter the plant price as a double>");
scanf("%lf", &(x->price));
printf("Enter the perdominant color of the plant>");
scanf("%s", &(x->color));
void displayPlant(struct Plant *x)
{
printf("\nThe cheapest plant is to be...\n");
printf("Plant ID %d which costs $%.2lf and the color is %s\n", x->plantID, x->price, x->color);
}
int findCheapestPlant(struct Plant x[], int length)
{
double lowest;
int index = -1;
int i = 0;
if (length > 0)
{
lowest = x[i].price;
}
for (i = 0; i < length; i++)
{
if (x[i].price < lowest)
{
index = i;
lowest = x[i].price;
}
}
return index;
}
}
I expect the display function to output the lowest price plant but i get errors.

There are multiple errors addressed in the comments, in addition to fixing these errors, the following should help you achieve what you want to do.
To get the code to display the index as well, maybe change the declaration of displayPlant to take the index as well:
displayPlant(struct Plant *x, int index)
and then pass the index you have in your main to the function like so
displayPlant(totalPlants[index], index);
Then of course you should alter your printf statement to something like:
printf("Plant ID %d (index: %d) which costs $%.2lf and the color is %s\n", x->plantID, index, x->price, x->color);
EDIT: I should also say that initializing your index to -1 is a bad idea, because it will result in seg faults unless your code includes checks for the index being >= 0.
Additionally add this index = i; or index = 0 here in your code:
if (length > 0)
{
lowest = x[i].price;
index = i; //here
}

Related

Updating specific elements in C array

I'm having trouble conceptualising how to go about some of my code.
My C program wishes to compare each individual element of an array of structs aka arr_person[i].name against a user's input to see if there's a match. (i.e. if the user types in "Billy" and "Billy" is also a string in arr_person[].name array)
for(i=0;i<num_of_lines;i++)
{
if(strcmp(nameInput, arr_person[i].name)==0) {
printf("Match at element %d\n", i);
}
}
Then, a separate function finds reoccurring elements within arr_person[i].name by iterating through the array, and if the same name occurs twice, it will take the corresponding integer values of the same elemental positions and will add them up and store in new variable newChange. For example, if "Billy" occurs twice in the array, at arr_person[0].name and arr_person[4].name, and arr_person[0].number = 15 and arr_person[4].number = 10, then I want to update the number such that it becomes 25.
for(i = 0; i < num_of_lines; i++) {
for(j=0;j<num_of_lines;j++) {
if(strcmp(arr_person[j].name, arr_person[i].name)==0)
*newNumber = arr_person[i].number + arr_person[j].number;
}
}
How do I go about this so that any elements in the array that don't reoccur are still kept the same?
If the user inputs "Rachel" and Rachel only appears once in the array, and her corresponding number is 85, I want to print
Rachel 85
But if the user inputs "Billy" and Billy occurs twice, and he has the two numbers 10 and 15 as corresponding integers in another array, I want to print
Billy 25
I've only been programming for a few months. Thanks in advance.
Seems like the only thing you need to do is this:
int sum = 0;
for(int i=0;i<num_of_lines;i++)
{
if(strcmp(nameInput, arr_person[i].name)==0)
sum += arr_person[i].number;
}
I would structure it like this:
// Previous code from your post slightly modified to function
// returns -1 on no match and index otherwise
int match(struct person *arr_person, char *nameInput, int num_of_lines)
{
for(int i=0;i<num_of_lines;i++) {
if(strcmp(nameInput, arr_person[i].name)==0)
return i;
}
return -1;
}
int sum(struct person *arr_person, char *nameInput, int num_of_lines)
{
int sum = 0;
for(int i=0;i<num_of_lines;i++) {
if(strcmp(nameInput, arr_person[i].name)==0)
sum += arr_person[i].number;
}
return sum;
}
int main()
{
// Insert code for declaration and initialization
int index = match(arr_person, nameInput, num_of_lines);
if(index >= 0) {
printf("Match at element %d\n", index);
printf("%s %d\n", nameInput, sum(arr_person, nameInput, num_of_lines));
} else {
printf("No match\n");
}
}

array inside function

Create a function to display array.
#include<stdio.h>
#define MAX_SIZE_ALLOTED_TO_EACH_QUESTION 100
#define NUMBER_OF_QUESTIONS 10
int scoreList[NUMBER_OF_QUESTIONS]; // This array will contain the individual score for each answers to respective questions
int i;
void Extroversion(int scoreList[]){
// Let formula for this be E = 20 +(1)___-(3)___+(2)___-(4)___
int E = 20 + (scoreList[1] + scoreList[2]) - (scoreList[3] + scoreList[4]);
printf("\nExtroversion is the personality trait of seeking fulfillment from sources outside the self or in community. High scorers tend to be very social while low scorers prefer to work on their projects alone.\nYour score for this trait is: %d\n\n", E);
}
void Agreeableness(int scoreList[]){
// Let formula for this be A = 14 -(2)___+(5)___-(3)___+(6)___
int A = 20 + (scoreList[5] + scoreList[6]) - (scoreList[2] + scoreList[3]);
printf("\nAgreeableness reflects much individuals adjust their behavior to suit others. High scorers are typically polite and like people. Low scorers tend to 'tell it like it is'.\nYour score for this trait is: %d\n\n", A);
}
/*
* Similarily for Conscientiousness, Neuroticism and Openness_to_Experience
*/
int main(){
const char question[NUMBER_OF_QUESTIONS][MAX_SIZE_ALLOTED_TO_EACH_QUESTION] = { "1. Am the life of the party.", "2. Feel little concern for others.", "3. Am always prepared.", "4. Get stressed out easily.", "5. Have a rich vocabulary.", "6. Don't talk a lot.", "7. Am interested in people.", "8. Leave my belongings around.", "9. Am relaxed most of the time.", "10. Have difficulty understanding abstract ideas." };
for(i=0; i<NUMBER_OF_QUESTIONS; i++){
printf("%s :\nYour Score: ", question[i]);
scanf("%d", &scoreList[i]); // Here each element is storing the value between 0-5 for their corresponsding question
}
Extroversion(scoreList);
Agreeableness(scoreList);
// Conscientiousness(scoreList);
// Neuroticism(scoreList);
// Openness_to_Experience(scoreList);
return 0;
}
I think it would be good for you to go through the code once. I have mentioned comments in the code using // and /* */. Read the comments properly. I have checked the code working for 10 questions on my system, so there would be no error if you complete following the pattern in which i have written. And don't forget to look at the formula. The array index need to be according to the formula in the original pdf you have shared.
#include<stdio.h>
#define SIZE 5
int scoreList[SIZE];
int i;
int findTotal(int scoreList[SIZE], int inSmall, int inLarge){
int total =0;
int index;
for (index = 0; index < SIZE; index++)
{
if (scoreList[index]!= inSmall && scoreList[index]!= inLarge)
total = total + scoreList[index];
}
return total;
}
int findLarge(int scoreList[SIZE]){
int index;
int largest = scoreList[0];
for (index=1; index < SIZE; index++)
{
if (scoreList[index] > largest)
largest = scoreList[index];
}
return largest;
}
int findSmall(int scoreList[SIZE]){
int index;
int smallest = scoreList[0];
for (index=1; index < SIZE; index++)
{
if (scoreList[index] < smallest)
smallest = scoreList[index];
}
return smallest;
}
int main(){
const char* question[] = { "I don't talk a lot", "I have people around me", "I love nature", "I talk about science", "And bla bla bla" };
// char question[SIZE][100] = {"I don't talk a lot","why this is good","one two","fourth","fifth"}; // If you don't wish to use pointer, You will have to use a 2D char array that will store the total number of element and second one will store length of each element (here 100)
for(i=0; i<SIZE; i++){
printf("%s :\nYour Score: ", question[i]);
scanf("%d", &scoreList[i]);
}
int smallest = findSmall(scoreList);
int largest = findLarge(scoreList);
int total = findTotal(scoreList, smallest, largest);
printf("smallest: %d, largest: %d, total: %d\n", smallest, largest, total);
return 0;
}
I have run it on my system. Working fine!

Problems with passing arrays as parameters

I am a novice programmer in C and am running into an issue that is almost painfully simple. I am writing a basic program that creates two arrays, one of student names and one of student ID numbers, then sorts them and prints them in various ways, and finally allows the user to search the arrays by ID number. Here is the code:
#include <stdio.h>
#include <string.h>
#define ARRAY_SIZE 3
#define MAX_NAME_LENGTH 32
int main()
{
// Student info arrays
char NAME[ARRAY_SIZE][MAX_NAME_LENGTH];
int ID[ARRAY_SIZE];
// Array for student IDs, shifted twice to the right
int shiftedID[ARRAY_SIZE];
// Boolean value to keep while loop running and
// the ID search prompt repeating
int loop = 1;
// Counter variable for the for loop
int counter;
// Gets input values for the student info arrays
for (counter = 0; counter < ARRAY_SIZE; counter++)
{
printf("Input student name: ");
scanf("%s", NAME[counter]);
printf("Input student ID: ");
scanf("%d", &ID[counter]);
}
// Sorts the arrays
sort(NAME, ID);
// Prints the arrays
print_array(&NAME, ID);
// Shifts the ID value two bits to the right
shiftright(ID, shiftedID);
print_array(NAME, shiftedID);
// Repeatedely prompts the user for an ID to
// search for
while(loop == 1)
{
search_id(NAME, ID);
}
}
And here are the function definitions:
#define ARRAY_SIZE 3
#define MAX_NAME_LENGTH 32
// Sorts the two arrays by student ID. (Bubble sort)
void sort(char **nameArray, int idArray[])
{
// Counter variables for the for loop
int firstCounter = 0;
int secondCounter = 0;
for(firstCounter = 0; firstCounter < ARRAY_SIZE; firstCounter++)
{
for(secondCounter = 0; secondCounter < ARRAY_SIZE - 1;
secondCounter++)
{
if(idArray[secondCounter] > idArray[secondCounter + 1])
{
// Temporary variables for the sort algorithm
int tempInt = 0;
char tempName[32];
tempInt = idArray[secondCounter + 1];
idArray[secondCounter + 1] = idArray[secondCounter];
idArray[secondCounter] = tempInt;
strcpy(tempName, nameArray[secondCounter + 1]);
strcpy(nameArray[secondCounter + 1],
nameArray[secondCounter]);
strcpy(nameArray[secondCounter], tempName);
}
}
}
}
// Searches the ID array for a user input student
// ID and prints the corresponding student's info.
void search_id(char **nameArray, int idArray[])
{
// A boolean value representing whether or not
// the input ID value was found
int isFound = 0;
// The input ID the user is searching for
int searchID = 0;
printf("Input student ID to search for: ");
scanf("%d", &searchID);
// Counter variable for the for loop
int counter = 0;
while (counter < ARRAY_SIZE && isFound == 0)
{
counter++;
if (idArray[counter] == searchID)
{
// Prints the name associated with the input ID
isFound = 1;
printf("%s", nameArray[counter]);
}
}
// If the input ID is not found, prints a failure message.
if (isFound == 0)
{
printf("ID not found.\n");
}
}
// Prints the name and ID of each student.
void print_array(char **nameArray, int idArray[])
{
// Counter variable for the for loop
int counter = 0;
printf("Student Name & Student ID: \n");
for (counter = 0; counter < ARRAY_SIZE; counter++)
{
printf("%s --- %d\n", nameArray[counter], idArray[counter]);
}
}
// Shifts the ID value to the right by two bits
void shiftright(int idArray[], int shiftedID[])
{
// Counter variable for the for loop
int counter = 0;
for (counter = 0; counter < ARRAY_SIZE; counter++)
{
shiftedID[counter] = idArray[counter] >> 2;
}
}
I am aware that this program is fairly basic in nature, and more than anything it is an exercise to get me more well versed in a language such as C. I've been working on it for some time, and have worked through several problems, but seem to be stuck on three issues:
If the input ID numbers are not input already in order, a segmentation fault results. If the ID numbers are input already in order, the sort function never passes through the if statement, and no problems arise.
When passing the arrays of names/IDs to the print_array function, the IDs are printed just fine, but the names will be printed either entirely blank or as a series of strange characters.
When searching by ID at the end of the program, the ID number that was entered first (so, the number in ID[0]) displays an ID not found message, where all numbers at index 1 or greater will work fine - aside from the corresponding names that should be printed being printed as blank, as mentioned in the second issue.
Any advice that I can get would be greatly appreciated! I find the power behind the fine details needed in C to be both really interesting but also very confusing, intimidatingly so, and that means any help I can get makes a big difference.
The problem is that you are assuming that char [ARRAY_SIZE][MAX_NAME_LENGTH] and char ** are interchangeable
void sort(char **nameArray, int idArray[])
should be
void sort(char nameArray[][MAX_NAME_LENGTH], int idArray[])
or
void sort(char (*nameArray)[MAX_NAME_LENGTH], int idArray[])
in order to use a pointer to an array of MAX_NAME_LENGTH chars, same for your search_id function.
Take a look to question 6.13 of C-FAQ
I would advise you to restructure your program. Rather than storing two independent arrays for names and IDs, you can store one array of structs which contain all the necessary data:
typedef struct student
{
int id;
char name[MAX_NAME_LENGTH];
} student_t;
student_t students[ARRAY_SIZE];
Now you have a single array which can never become "mismatched" by sorting the IDs without the names, etc.
You can sort an array in C using the standard library function qsort():
qsort(students, ARRAY_SIZE, sizeof(student_t), comparator);
This requires you define a comparator, which is fairly simple. One example would be:
int comparator(const void *lhs, const void *rhs)
{
const student_t *s1 = lhs, *s2 = rhs;
return s1->id - s2->id;
}
You can use the same comparator with another standard library function bsearch() to search the array of students after it is sorted:
student_t key = { 42 }; // name doesn't matter, search by ID
student_t* result = bsearch(&key, students, ARRAY_SIZE, sizeof(student_t), comparator);
These standard functions are more efficient than what you had, and require you to write much less code, with fewer chances for mistakes.

How will I print the highest scorer (with it's other "struc mates") using a function. C

Beginner in C here, please bear with my question since I am having a hard time explaining it. And I'm really sorry if my terms are incorrect. I hope you get it.
Say that I have my struct like this:
struct studentType
{
char studentFName[20];
char studentLName[20];
int score;
char grade;
}s[20];
and I have inputted 3 elements in to s. Now I have compared each others score,
through this:
void getHighestScorer(struct studentType s[20])
{
int maximum, i;
maximum = s[0].score;
for(i=0;i<3;i++)
{
if (s[i].score > maximum)
{
maximum = s[i].score;
}
}
}
and I have found that s[2] has the highest score compared to the others. How will I actually print that one on another function with its other "struc mates"
I actually tried doing it on the function above like this(and it didn't work):
void getHighestScorer(struct studentType s[20])
{
int maximum, i;
maximum = s[0].score;
for(i=0;i<3;i++)
{
if (s[i].score > maximum)
{
maximum = s[i].score;
}
}
printf("The highest scorer is: %s, %s %d\n", s[i].studentLName,s[i].studentFName,
s[i].score);
}
My whole program is here
Define the function the following way
int getHighestScorer( struct studentType s[], size_t n )
{
int maximum;
size_t i;
if ( n == 0 ) return 0;
maximum = s[0].score;
for ( i = 1; i < n; i++ )
{
if ( maximum < s[i].score ) maximum = s[i].score;
}
return maximum;
}
and use it like
printf( "Maximum score is %d\n", getHighestScorer( s, 3 ) );
Or another approach
size_t getHighestScorer( struct studentType s[], size_t n )
{
size_t maximum = 0;
size_t i = 1;
for ( ; i < n; i++ )
{
if ( s[maximum] < s[i].score ) maximum = i;
}
return maximum;
}
And use it like
size_t i = getHighestScorer( s, 3 );
printf("The highest scorer is: %s, %s %d\n", s[i].studentLName,s[i].studentFName,
s[i].score);
What you are doing is you are iterating over array till index 3 (i<3) and hence i value at the end of loop would always be 3. So maintain index of last max item.
void getHighestScorer(struct studentType s[20])
{
int maximum, i, index = 0;
maximum = s[0].score;
for(i=1;i<3;i++)//should start with 1 as 0 you are considering is max
{
if (s[i].score > maximum)
{
maximum = s[i].score;
index = i;
}
}
printf("The highest scorer is: %s, %s %d\n", s[index].studentLName,s[index].studentFName,
s[index].score);
}
Hope this is what you are after.
If you want to pass this struct in another function, change this method to return the index and in that method accept your struct and index (that above function would pass) and use your same printf statement that should work.
What do you mean by "struc mates"?
If it means you want to print the other members of the struct along with the score member,
then the following should help:
void printHighestScorer(struct studentType s[20]) //this the function wherein I don't know what to put//
{
int maximum, i;
int maxIndex = 0;
maximum = s[0].score;
for(i=0;i<3;i++)
{
if (s[i].score > maximum)
{
maximum = s[i].score;
maxIndex = i;
}
}
printf("The highest scorer is: %s, %s %d\n", s[maxIndex].studentLName,s[maxIndex].studentFName,
s[maxIndex].score);
}
Basically you need to store the index of the struct variable which contains the maximum score.

searching within an array of structs in c

i see plenty of examples on how to search arrays to find a specific instance what i want to do is find all the instances and print them for example i have this struct
struct BookInfo
{
char title[50];
int numAuthors;
char authors[50][50];
int year;
int checkedout;
};
struct BookInfo library[500];
and i have a function to search within the years but it only gives me the first instance it finds how do i get it to give me bot instances???
heres the function
int yearsearch()
{
int target, i, l, r, mid;
l = 0;
r = 14-1;
printf("type a year to search for book");
scanf("%d", &target);
while(l <= r)
{
mid = (l+r)/2;
if(library[mid].year == target)
{
printf("\n%s",library[mid].title);
printf(" %d",library[mid].year);
printf("These are all the books with that year");
break;
}
else if (library[mid].year < target)
{
l = mid + 1;
}
else
{
r = mid - 1;
}
if(l > r)
printf("The target is not in the array.\n");
}
menu();
}
You're doing a kind of binary search over the array, which is not designed to find all instances without modification. Have you considered just doing a linear search (i.e., a for loop) over the length of the array and printing if the array element matches your search criteria? One might implement a naive linear search like this:
for (int i = 0; i<500; i++) {
if (library[i].year == target) {
// Do your printing here
}
// Otherwise do nothing!
}

Resources