C Program To Choose Cars By Given Conditions
In this article, you will learn how to write C programs that can filter and select cars based on various user-defined conditions, simulating a basic car inventory search.
Problem Statement
Managing and searching through car inventories can be challenging, especially when users need to find vehicles matching specific criteria like price range, make, year, or features such as being electric. The core problem is efficiently filtering a dataset of cars using dynamically applied conditions, which is crucial for applications ranging from dealership management systems to online car marketplaces.
Example
Consider a list of cars. If we want to find all cars priced under $25,000, a simple program would output:
Honda Civic (2020) - Price: $22000.00, Electric: No
Toyota Corolla (2021) - Price: $23500.00, Electric: No
Background & Knowledge Prerequisites
To follow this tutorial, readers should have a basic understanding of:
- C programming fundamentals: Variables, data types, loops (for, while), conditional statements (if-else).
- Structures in C: Defining and using
structto group related data. - Arrays: Declaring and iterating over arrays of structures.
- Functions: Defining and calling functions.
No special libraries or complex setup are required beyond a standard C compiler (like GCC).
Use Cases or Case Studies
Filtering data based on conditions is a fundamental task with broad applications:
- Online Car Dealerships: Customers can search for cars by make, model, year, price, mileage, or specific features (e.g., "electric" or "AWD").
- Inventory Management Systems: Dealerships use such programs internally to track stock, identify cars for promotions, or find vehicles needing specific maintenance.
- Market Research: Analysts can filter car data to identify trends, popular models, or pricing strategies in different segments.
- Personal Car Shopping Tools: Individuals can create custom scripts to scrape and filter car listings from various websites based on their preferences.
- Fleet Management: Organizations managing a fleet of vehicles might filter by vehicle type, last service date, or operational status.
Solution Approaches
Here, we explore three approaches to filtering cars, progressively increasing in flexibility.
Approach 1: Simple Filtering for a Single Condition
This approach demonstrates filtering cars based on a single, direct condition using an if statement within a loop.
- One-line summary: Iterate through a list of cars and print only those that meet a single specified criterion.
// Filter Cars by Price
#include <stdio.h>
#include <string.h> // Required for strcpy
// Define a structure for a car
struct Car {
char make[20];
char model[20];
int year;
float price;
int is_electric; // 1 for electric, 0 for gasoline
};
int main() {
// Step 1: Initialize an array of Car structures
struct Car inventory[5];
strcpy(inventory[0].make, "Honda");
strcpy(inventory[0].model, "Civic");
inventory[0].year = 2020;
inventory[0].price = 22000.00;
inventory[0].is_electric = 0;
strcpy(inventory[1].make, "Tesla");
strcpy(inventory[1].model, "Model 3");
inventory[1].year = 2022;
inventory[1].price = 45000.00;
inventory[1].is_electric = 1;
strcpy(inventory[2].make, "Toyota");
strcpy(inventory[2].model, "Corolla");
inventory[2].year = 2021;
inventory[2].price = 23500.00;
inventory[2].is_electric = 0;
strcpy(inventory[3].make, "Nissan");
strcpy(inventory[3].model, "Leaf");
inventory[3].year = 2023;
inventory[3].price = 32000.00;
inventory[3].is_electric = 1;
strcpy(inventory[4].make, "Ford");
strcpy(inventory[4].model, "Mustang");
inventory[4].year = 2020;
inventory[4].price = 35000.00;
inventory[4].is_electric = 0;
// Step 2: Define the filtering condition (e.g., cars under a specific price)
float max_price = 25000.00;
printf("Cars priced under $%.2f:\\n", max_price);
// Step 3: Iterate through the inventory and apply the filter
for (int i = 0; i < 5; i++) {
if (inventory[i].price < max_price) {
printf("%s %s (%d) - Price: $%.2f, Electric: %s\\n",
inventory[i].make, inventory[i].model, inventory[i].year,
inventory[i].price, inventory[i].is_electric ? "Yes" : "No");
}
}
return 0;
}
- Sample output:
Cars priced under $25000.00:
Honda Civic (2020) - Price: $22000.00, Electric: No
Toyota Corolla (2021) - Price: $23500.00, Electric: No
- Stepwise explanation:
- A
Carstructure is defined to hold details likemake,model,year,price, andis_electric. - An array
inventoryis populated with five car records. - A
max_pricevariable sets the filtering threshold. - The program then loops through each car in the
inventoryarray. - Inside the loop, an
ifstatement checks if the current car'spriceis less thanmax_price. - If the condition is true, the car's details are printed.
Approach 2: Filtering with Multiple Conditions (AND/OR Logic)
This method extends the basic filtering to handle multiple criteria simultaneously using logical operators (&& for AND, || for OR).
- One-line summary: Filter cars by combining several conditions using logical AND or OR operators.
// Filter Cars by Multiple Conditions
#include <stdio.h>
#include <string.h>
// Define a structure for a car (same as Approach 1)
struct Car {
char make[20];
char model[20];
int year;
float price;
int is_electric; // 1 for electric, 0 for gasoline
};
int main() {
// Step 1: Initialize an array of Car structures (same as Approach 1)
struct Car inventory[5];
strcpy(inventory[0].make, "Honda");
strcpy(inventory[0].model, "Civic");
inventory[0].year = 2020;
inventory[0].price = 22000.00;
inventory[0].is_electric = 0;
strcpy(inventory[1].make, "Tesla");
strcpy(inventory[1].model, "Model 3");
inventory[1].year = 2022;
inventory[1].price = 45000.00;
inventory[1].is_electric = 1;
strcpy(inventory[2].make, "Toyota");
strcpy(inventory[2].model, "Corolla");
inventory[2].year = 2021;
inventory[2].price = 23500.00;
inventory[2].is_electric = 0;
strcpy(inventory[3].make, "Nissan");
strcpy(inventory[3].model, "Leaf");
inventory[3].year = 2023;
inventory[3].price = 32000.00;
inventory[3].is_electric = 1;
strcpy(inventory[4].make, "Ford");
strcpy(inventory[4].model, "Mustang");
inventory[4].year = 2020;
inventory[4].price = 35000.00;
inventory[4].is_electric = 0;
// Step 2: Define multiple filtering conditions
float min_price = 30000.00;
int required_electric = 1; // 1 for electric, 0 for non-electric
printf("\\nCars priced above $%.2f AND are electric:\\n", min_price);
// Step 3: Iterate and apply combined filter conditions
for (int i = 0; i < 5; i++) {
if (inventory[i].price > min_price && inventory[i].is_electric == required_electric) {
printf("%s %s (%d) - Price: $%.2f, Electric: %s\\n",
inventory[i].make, inventory[i].model, inventory[i].year,
inventory[i].price, inventory[i].is_electric ? "Yes" : "No");
}
}
printf("\\nCars from year 2020 OR electric:\\n");
for (int i = 0; i < 5; i++) {
if (inventory[i].year == 2020 || inventory[i].is_electric == 1) {
printf("%s %s (%d) - Price: $%.2f, Electric: %s\\n",
inventory[i].make, inventory[i].model, inventory[i].year,
inventory[i].price, inventory[i].is_electric ? "Yes" : "No");
}
}
return 0;
}
- Sample output:
Cars priced above $30000.00 AND are electric:
Tesla Model 3 (2022) - Price: $45000.00, Electric: Yes
Nissan Leaf (2023) - Price: $32000.00, Electric: Yes
Cars from year 2020 OR electric:
Honda Civic (2020) - Price: $22000.00, Electric: No
Tesla Model 3 (2022) - Price: $45000.00, Electric: Yes
Nissan Leaf (2023) - Price: $32000.00, Electric: Yes
Ford Mustang (2020) - Price: $35000.00, Electric: No
- Stepwise explanation:
- The
Carstructure and inventory initialization are identical to Approach 1. - We introduce two sets of filtering conditions: one with
&&(AND) and another with||(OR). - For the
ANDcondition, cars are selected only if theirpriceis abovemin_priceAND they areis_electric. - For the
ORcondition, cars are selected if theiryearis2020OR they areis_electric. - Each loop iterates through the inventory, and the
ifstatement evaluates the combined logical expression. Only cars satisfying the entire expression are printed.
Approach 3: Using a Function to Encapsulate Filter Logic
To make the code more modular and reusable, the filtering logic can be extracted into a separate function. This allows for cleaner main functions and easier changes to filtering rules.
- One-line summary: Define a dedicated function that takes a
Carstruct and condition parameters, returning true if the car matches the criteria.
// Modular Car Filter Function
#include <stdio.h>
#include <string.h>
// Define a structure for a car
struct Car {
char make[20];
char model[20];
int year;
float price;
int is_electric;
};
// Step 1: Define a filter function
// This function returns 1 if the car matches the criteria, 0 otherwise.
int matches_criteria(struct Car car, int min_year, float max_price, int must_be_electric) {
int matches = 1; // Assume it matches initially
if (min_year > 0 && car.year < min_year) {
matches = 0; // Does not match year
}
if (max_price > 0 && car.price > max_price) {
matches = 0; // Does not match price
}
if (must_be_electric == 1 && car.is_electric == 0) {
matches = 0; // Must be electric but isn't
}
// No specific condition for must_be_electric == 0 (don't care if electric or not)
// If must_be_electric is -1, it means we don't care about electric status.
// Let's refine for a clear 'must_be_electric' or 'must_not_be_electric' or 'don't care'
// For simplicity, 1 means must be electric, 0 means must not be electric, -1 means don't care.
if (must_be_electric == 1 && car.is_electric == 0) { // Must be electric, but isn't
matches = 0;
} else if (must_be_electric == 0 && car.is_electric == 1) { // Must not be electric, but is
matches = 0;
}
return matches;
}
int main() {
// Step 2: Initialize an array of Car structures (same as previous approaches)
struct Car inventory[5];
strcpy(inventory[0].make, "Honda");
strcpy(inventory[0].model, "Civic");
inventory[0].year = 2020;
inventory[0].price = 22000.00;
inventory[0].is_electric = 0;
strcpy(inventory[1].make, "Tesla");
strcpy(inventory[1].model, "Model 3");
inventory[1].year = 2022;
inventory[1].price = 45000.00;
inventory[1].is_electric = 1;
strcpy(inventory[2].make, "Toyota");
strcpy(inventory[2].model, "Corolla");
inventory[2].year = 2021;
inventory[2].price = 23500.00;
inventory[2].is_electric = 0;
strcpy(inventory[3].make, "Nissan");
strcpy(inventory[3].model, "Leaf");
inventory[3].year = 2023;
inventory[3].price = 32000.00;
inventory[3].is_electric = 1;
strcpy(inventory[4].make, "Ford");
strcpy(inventory[4].model, "Mustang");
inventory[4].year = 2020;
inventory[4].price = 35000.00;
inventory[4].is_electric = 0;
// Step 3: Use the filter function with different criteria
printf("Cars from year 2022 or newer, max price $50000, and must be electric:\\n");
for (int i = 0; i < 5; i++) {
if (matches_criteria(inventory[i], 2022, 50000.00, 1)) {
printf("%s %s (%d) - Price: $%.2f, Electric: %s\\n",
inventory[i].make, inventory[i].model, inventory[i].year,
inventory[i].price, inventory[i].is_electric ? "Yes" : "No");
}
}
printf("\\nCars from year 2020 or newer, no max price, and must NOT be electric:\\n");
for (int i = 0; i < 5; i++) {
if (matches_criteria(inventory[i], 2020, -1.0, 0)) { // -1 for max_price means no limit
printf("%s %s (%d) - Price: $%.2f, Electric: %s\\n",
inventory[i].make, inventory[i].model, inventory[i].year,
inventory[i].price, inventory[i].is_electric ? "Yes" : "No");
}
}
return 0;
}
- Sample output:
Cars from year 2022 or newer, max price $50000, and must be electric:
Tesla Model 3 (2022) - Price: $45000.00, Electric: Yes
Nissan Leaf (2023) - Price: $32000.00, Electric: Yes
Cars from year 2020 or newer, no max price, and must NOT be electric:
Honda Civic (2020) - Price: $22000.00, Electric: No
Toyota Corolla (2021) - Price: $23500.00, Electric: No
Ford Mustang (2020) - Price: $35000.00, Electric: No
- Stepwise explanation:
- A
matches_criteriafunction is created. It takes aCarstructure and specific filter parameters (min_year,max_price,must_be_electric). - Inside
matches_criteria, it performs a series ofifchecks. If any condition fails, it immediately setsmatchesto 0. Special values (like0formin_yearor-1.0formax_price, or-1formust_be_electricas a "don't care") can be used to indicate that a specific criterion should be ignored. - The
mainfunction initializes the car inventory. - Instead of in-line
ifstatements, theforloops now callmatches_criteria, passing the current car and the desired filter parameters. - This approach greatly enhances readability and allows for easy modification or addition of new filter combinations without altering the main loop logic.
Conclusion
Filtering data based on conditions is a fundamental programming task. By defining clear data structures and using conditional logic, C programs can effectively select specific items from a collection. Whether using simple if statements for basic checks, combining multiple conditions with logical operators, or encapsulating complex logic within functions for better modularity, the core principle remains to iterate through data and apply criteria.
Summary
- Data Structure: Use
structto represent complex data entities likeCarobjects. - Single Condition: Filter efficiently using simple
ifstatements within a loop. - Multiple Conditions: Combine conditions using
&&(AND) and||(OR) logical operators for complex searches. - Modularity: Encapsulate filtering logic within functions to improve code organization, readability, and reusability.
- Parameters: Design filter functions to accept parameters, making them flexible for various search criteria.