/*
* Author: [Your Name]
* Course: CS& 131, Fall 2026
* Assignment: Programming Project #5 - Gerrymandering Part 1
*
* Description: Reads election district vote data from a CSV file, computes
* district-level and state-level vote counts and percentages, determines
* state winners, and displays national election totals and the overall winner.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DATA_FILE "districts.csv"
#define MAX_DISTRICTS 55
#define MAX_LINE_LENGTH 800
// Function prototypes
void print_intro(void);
int parse_line(char line[], char state[], int dem_votes[], int rep_votes[]);
void compute_district_percentages(const int dem_votes[], const int rep_votes[],
int dem_pct[], int rep_pct[], int num_districts);
int sum_array(const int arr[], int size);
void print_int_array(const int arr[], int size, int include_percent);
void print_state_results(const char state[], const int dem_votes[],
const int rep_votes[], int num_districts);
void print_national_results(long total_dem, long total_rep);
int main(void) {
FILE *file = fopen(DATA_FILE, "r");
if (file == NULL) {
printf("Error: Could not open file %s\n", DATA_FILE);
return 1;
}
print_intro();
char line[MAX_LINE_LENGTH];
char state[MAX_LINE_LENGTH];
int dem_votes[MAX_DISTRICTS];
int rep_votes[MAX_DISTRICTS];
long national_dem_votes = 0;
long national_rep_votes = 0;
// Read each state line once and process its election results
while (fgets(line, MAX_LINE_LENGTH, file) != NULL) {
// Strip trailing newline characters if present
line[strcspn(line, "\r\n")] = '\0';
if (strlen(line) == 0) {
continue;
}
int num_districts = parse_line(line, state, dem_votes, rep_votes);
print_state_results(state, dem_votes, rep_votes, num_districts);
national_dem_votes += sum_array(dem_votes, num_districts);
national_rep_votes += sum_array(rep_votes, num_districts);
}
fclose(file);
print_national_results(national_dem_votes, national_rep_votes);
return 0;
}
/*
* Prints the introductory welcome banner for the program.
*/
void print_intro(void) {
printf("Welcome to the election results viewer!\n");
printf("This program calculates the results of an election\n");
printf("and displays them by district, state and overall.\n\n");
}
/*
* Parses a single CSV line into the state name and parallel arrays of
* Democratic and Republican vote counts. Returns the number of districts.
*/
int parse_line(char line[], char state[], int dem_votes[], int rep_votes[]) {
char *token = strtok(line, ",");
if (token != NULL) {
strcpy(state, token);
}
int count = 0;
// Each district is stored in groups of 3: district number, dem votes, rep votes
while ((token = strtok(NULL, ",")) != NULL && count < MAX_DISTRICTS) {
// Skip district number token, read Democratic votes
token = strtok(NULL, ",");
if (token != NULL) {
dem_votes[count] = atoi(token);
}
// Read Republican votes
token = strtok(NULL, ",");
if (token != NULL) {
rep_votes[count] = atoi(token);
}
count++;
}
return count;
}
/*
* Computes integer vote percentages for each district, safely handling
* districts with 0 total votes to prevent division by zero.
*/
void compute_district_percentages(const int dem_votes[], const int rep_votes[],
int dem_pct[], int rep_pct[], int num_districts) {
for (int i = 0; i < num_districts; i++) {
long total = (long)dem_votes[i] + rep_votes[i];
if (total == 0) {
dem_pct[i] = 0;
rep_pct[i] = 0;
} else {
dem_pct[i] = (int)(((long)dem_votes[i] * 100) / total);
rep_pct[i] = (int)(((long)rep_votes[i] * 100) / total);
}
}
}
/*
* Calculates and returns the sum of all integers in an array.
*/
int sum_array(const int arr[], int size) {
int total = 0;
for (int i = 0; i < size; i++) {
total += arr[i];
}
return total;
}
/*
* Prints an integer array formatted as [v1, v2, ...] with optional '%' signs.
*/
void print_int_array(const int arr[], int size, int include_percent) {
printf("[");
for (int i = 0; i < size; i++) {
printf("%d", arr[i]);
if (include_percent) {
printf("%%");
}
if (i < size - 1) {
printf(", ");
}
}
printf("]");
}
/*
* Computes and displays all vote counts, percentages, and the winning party
* for a single state.
*/
void print_state_results(const char state[], const int dem_votes[],
const int rep_votes[], int num_districts) {
int dem_pct[MAX_DISTRICTS];
int rep_pct[MAX_DISTRICTS];
compute_district_percentages(dem_votes, rep_votes, dem_pct, rep_pct, num_districts);
long state_dem_total = sum_array(dem_votes, num_districts);
long state_rep_total = sum_array(rep_votes, num_districts);
long state_total = state_dem_total + state_rep_total;
int state_dem_pct = 0;
int state_rep_pct = 0;
if (state_total > 0) {
state_dem_pct = (int)((state_dem_total * 100) / state_total);
state_rep_pct = (int)((state_rep_total * 100) / state_total);
}
printf("State of %s:\n", state);
printf("Democratic Vote Counts: ");
print_int_array(dem_votes, num_districts, 0);
printf("\n");
printf("Republican Vote Counts: ");
print_int_array(rep_votes, num_districts, 0);
printf("\n");
printf("Democratic Vote Percentage: ");
print_int_array(dem_pct, num_districts, 1);
printf(" = %d%% total\n", state_dem_pct);
printf("Republican Vote Percentage: ");
print_int_array(rep_pct, num_districts, 1);
printf(" = %d%% total\n", state_rep_pct);
if (state_dem_total > state_rep_total) {
printf("The Democratic candidate won.\n\n");
} else {
printf("The Republican candidate won.\n\n");
}
}
/*
* Computes and prints the national vote percentages and overall winning party.
*/
void print_national_results(long total_dem, long total_rep) {
long total_votes = total_dem + total_rep;
int nat_dem_pct = 0;
int nat_rep_pct = 0;
if (total_votes > 0) {
nat_dem_pct = (int)((total_dem * 100) / total_votes);
nat_rep_pct = (int)((total_rep * 100) / total_votes);
}
printf("The Democrats won %d%% of the national votes.\n", nat_dem_pct);
printf("The Republicans won %d%% of the national votes.\n", nat_rep_pct);
if (total_dem > total_rep) {
printf("The Democratic candidate won.\n");
} else {
printf("The Republican candidate won.\n");
}
}
To embed this project on your website, copy the following code and paste it into your website's HTML: