2

The program should count which candidate get the most votes; and should act like:

$ ./plurality Alice Bob
Number of voters: 3
Vote: Alice
Vote: Charlie
Invalid vote.
Vote: Alice
Alice

If there are multiple candidates with a same number of votes program should print out 2 names:

$ ./plurality Alice Bob Charlie
Number of voters: 5
Vote: Alice
Vote: Charlie
Vote: Bob
Vote: Bob
Vote: Alice
Alice
Bob

For more information check out https://cs50.harvard.edu/x/2023/psets/3/plurality/

Here is my version of the code:

#include <cs50.h>
#include <stdio.h>
#include <string.h>

// Max number of candidates
#define MAX 9

// Candidates have name and vote count
typedef struct
{
    string name;
    int votes;
}
candidate;

// Array of candidates
candidate candidates[MAX];

// Number of candidates
int candidate_count;

// Function prototypes
bool vote(string name);
void print_winner(void);

int main(int argc, string argv[])
{
    // Check for invalid usage
    if (argc < 2)
    {
        printf("Usage: plurality [candidate ...]\n");
        return 1;
    }

    // Populate array of candidates
    candidate_count = argc - 1;
    if (candidate_count > MAX)
    {
        printf("Maximum number of candidates is %i\n", MAX);
        return 2;
    }
    for (int i = 0; i < candidate_count; i++)
    {
        candidates[i].name = argv[i + 1];
        candidates[i].votes = 0;
    }

    int voter_count = get_int("Number of voters: ");

    // Loop over all voters
    for (int i = 0; i < voter_count;)
    {
        string name = get_string("Vote: ");

        // Check for invalid vote
        if (!vote(name))
        {
            printf("Invalid vote.\n");
        }
        else
        {
            i++;
        }
    }

    // Display winner of election
    print_winner();
}

// Update vote totals given a new vote
bool vote(string name)
{
    for (int i = 0; i < candidate_count; i++)
    {
        if (strcmp(name, candidates[i].name) == 0)
        {
            candidates[i].votes = candidates[i].votes + 1;
            return true;
        }
    }
    return false;
}

// Print the winner (or winners) of the election
void print_winner(void)
{
    char t[100];
    for (int i = 0; i < candidate_count; i++)
    {
        for (int j = 0; j < candidate_count - i - 1; j++)
        {
            if (candidates[j].votes < candidates[j + 1].votes)
            {

                int temp = candidates[j].votes;
                candidates[j].votes = candidates[j + 1].votes;
                candidates[j + 1].votes = temp;

                strcpy(t, candidates[j].name);
                strcpy(candidates[j].name, candidates[j + 1].name);
                strcpy(candidates[j + 1].name, t);
            }
        }
    }
    printf("%s\n", candidates[0].name);
    for(int k = 1; k < candidate_count; k++)
    {
        if (candidates[0].votes == candidates[k].votes)
        {
            printf("%s\n", candidates[k].name);
        }
    }

    return;
}

It works with examples i come up with, however automatic program check50 which is used to check answer results:

:) plurality.c exists
:) plurality compiles
:) vote returns true when given name of first candidate
:) vote returns true when given name of middle candidate
:) vote returns true when given name of last candidate
:) vote returns false when given name of invalid candidate
:) vote produces correct counts when all votes are zero
:) vote produces correct counts after some have already voted
:) vote leaves vote counts unchanged when voting for invalid                             candidate
:) print_winner identifies Alice as winner of election
:( print_winner identifies Bob as winner of election
    print_winner function did not print winner of election
:( print_winner identifies Charlie as winner of election
    print_winner function did not print winner of election
:) print_winner prints multiple winners in case of tie
:) print_winner prints all names when all candidates are tied

I can't see what the problem is, and my debugger doesn't show candidate[j].votes or candidate[j].name values, so i'm lost. Please help.

Edit: array t contains 100 elements so i wont get a segmentation fault, eventho the task doesn't require strings of bigger sizes, so it isn't where problem is

  • You probably would enjoy the options to control how your post looks with this info: https://stackoverflow.com/editing-help – Yunnosch Jul 05 '23 at 18:51
  • 3
    When you sort, you use `strcpy` on the names. But the names point to the `argv` array, and copying in to that might be a problem if the string is too long. – 001 Jul 05 '23 at 19:02
  • `"I can't see what the problem is, and my debugger doesn't show candidate[j].votes or candidate[j].name values, so i'm lost."` -- Most debuggers allow you to add a list of variables that you want to "watch". Did you do that for the variables that you mentioned? Does the debugger say that it can't display the values for these variables? Or are you having trouble telling your debugger that you want to watch these variables? – Andreas Wenzel Jul 05 '23 at 19:07
  • 3
    Instead of using `strcpy()` to copy the strings, just swap the pointers. – Barmar Jul 05 '23 at 19:09
  • i've no idea how to allow my debugger to add variables, i use online vscode from cs50, and there isn't many guides on how to do that – Bulat_Ishet_otvety Jul 06 '23 at 06:37
  • @Bulat_Ishet_otvety: In the [video of week 2 of CS50](https://cs50.harvard.edu/x/2023/weeks/2/), at the time 48:10, I see a field labelled "WATCH" in the debugger. I guess you must open that field and then add a variable to watch. – Andreas Wenzel Jul 06 '23 at 07:06
  • @Bulat_Ishet_otvety: I have now tested this with debug50. In order to add a variable to watch, all you have to do is right-click into the "WATCH" area, and then type the expression to watch, for example `candidate[j].votes`. – Andreas Wenzel Jul 06 '23 at 23:49

2 Answers2

0

Look at your logic in the print_winner function.

You have sorted the array in increasing order. The maximum vote getter will be found at index value candidate_count - 1, not at index 0.

You have written:

for(int k = 1; k < candidate_count; k++)
    {
        if (candidates[0].votes == candidates[k].votes)
        {
            printf("%s\n", candidates[k].name);
        }
    }

This loop compares candidates[0].votes, which is the candidate with the minimum votes, with candidate[k].votes. Try comparing candidates[candidate_count - 1].votes with candidates[k].votes. The maximum vote getter will be at candidates[candidate_count - 1].

Jim Rogers
  • 4,822
  • 1
  • 11
  • 24
0

i've change the whole structs instead of single strings and it worked, also changing pointers worked, so thx everyone

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 12 '23 at 21:18