how do I assign values from text file to a structu

2019-09-10 11:02发布

问题:

I have to do an election program in C.

There are 7 candidates and 365 votes in total. I need to do this using an array of structures. I need to read from a text file each of the names of the candidate and the number of votes they get. At the end i need to output the winner of the election.

Here is a sample of my code so far

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

    struct candidates {
        char name[20];
        int votes;
    };


    int main()

     {
        //Counter
        int i = 0;
        int gVotes = 0;
        //Votes counter
        int v = 0;
        //Sploit Vote
        int spVote = 0;

struct candidates electionCandidate[7];
FILE *fp;
fp = fopen("elections.txt", "r");
for(i=0;i<7;i++)
    {
      char * aNames = fgets(electionCandidate[i].name, 20, fp);
    }

//for testing each candidate gots their name
for(i=0;i<7;i++)
    {
        printf("%d. Candidate is %s\n\n", i+1, electionCandidate[i]);
    }  
 //For 365 Votes

 while (!feof(fp))
       {
            int iVoteFor = 0;
            fscanf(fp, "%d", &iVoteFor);
            electionCandidate[iVoteFor-1].votes++;
            //gVotes is my counter for the number of entries. 
            printf("%d ", ++gVotes);
        }

        system("pause");

        return 0; 
    }
            //Ideas of what to use

Here is my current elections.txt

Robert Bloom
John Brown
Michelle Dawn
Michael Hall
Sean O’Rielly
Arthur Smith
Carl White


3 3 81 1 2 3 1 2 4 5 
1 6 12 9 6 5 0 2
8 46 6 8 3 2 8 0 12 6 1 8 
3 11 7 5 5 8 9 10 12 1 3 12 
2 23 2 5 7 4 11 8 6 11 12 
9 11 7 9 3 1 2 10 12 
12 7 11 9 6 6 0 1 10 7 11 2 8 
0 12 8 10 11 2 2 8 4 2 12 3 2 9 1 
4 88 7 7 4 12 2 10 10 9 4 12 9 3 12 
0 48 0 6 5 9 0 5 3 11 6 0 3 0 1 2 3 
4 1 1 2 3 3 3 3 3 3 3 3 3 3 8 4 5 
9 1 2 12 1 7 7 7 7 7 7 7 7 7 7 7 4 7 1 2 
4 5 1 2 3 1 2 8 7 12 95 41 1 7 5 4 4 4 4 4 
4 4 4 4 4 4 4 4 4 1 1 1 1 6 6 6 6 6 7 7 7 7
7 8 8 9 9 8 7 7 1 1 2 3 5 4 4 6 8 7 52 1 4 7 
5 2 5 4 7 7 7 7 7 7 7 4 7 7 7 1 2 5 4 7 8 7 4 1
4 7 8 7 4 1 5 2 5 2 3 6 5 3 2 1 2 1 2 3 
2 2 5 1 4 7 7 7 7 7 7 7 7 7 7 7 7 1 2 1 
3 4 5 1 2 3 1 2 3 1 4 5 8 1 2 4 1 4 2 5 
6 7 8 1 2 3 3 4 7 7 7 7 7 7 7 8 1 2 3 4 

EDIT:

Each candidate gets +1 vote for their number electionCandidate[0] for each one he gets one vote and so on for the rest. 365 voters in total.

I was able to input the name for each Candidate from the text file. Now the problem is putting each vote to the corresponding candidate. Also any vote that is above 7 is a spoilt vote which i am trying to count in the above code. The code compiles but it crashes.

I am using while(!feof) but it seems that its not working or this is not the correct way. Any suggestions.

EDIT: I am using the debugger and find that it runs for a few times around the while(!feof) but in one of the instances it gives the error and stops.

EDIT: By commenting out the line electionCandidate[iVoteFor-1].votes++; the program reads all the way to 365 value.

how do I assign each to vote to each candidate?

回答1:

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

struct candidate
{
    char name[20];
    int votes;
};

enum { MAX_CANDIDATES = 7 };

static int vote_cmp(const void *vp1, const void *vp2)
{
  int votes1 = ((const struct candidate *)vp1)->votes;
  int votes2 = ((const struct candidate *)vp2)->votes;
  if (votes1 < votes2)
    return -1;
  else if (votes1 > votes2)
    return +1;
  else
    return 0;
}

int main(void)
{
  struct candidate electionCandidate[MAX_CANDIDATES];

  char buffer[4096];
  size_t i;
  for (i = 0; fgets(buffer, sizeof(buffer), stdin) != 0; i++)
  {
    if (strlen(buffer) < 2)
      break;  // Blank line
    if (i >= MAX_CANDIDATES)
    {
      fprintf(stderr, "Too many candidates: %s", buffer);
      return 1;
    }
    size_t len = strlen(buffer);
    if (len >= sizeof(electionCandidate[i].name))
    {
      fprintf(stderr, "Candidate name too long: %s", buffer);
      return 1;
    }
    memmove(electionCandidate[i].name, buffer, len - 1);
    electionCandidate[i].name[len] = '\0';
    electionCandidate[i].votes = 0;
  }

  size_t n_cand = i;
  int spoiled = 0;
  unsigned votefor;
  while (scanf("%u", &votefor) == 1)
  {
    if (votefor == 0 || votefor > n_cand)
      spoiled++;
    else
      electionCandidate[votefor-1].votes++;
  }

  qsort(electionCandidate, n_cand, sizeof(electionCandidate[0]), vote_cmp);

  for (i = 0; i < n_cand; i++)
    printf("%20s: %3d\n", electionCandidate[i].name, electionCandidate[i].votes);
  putchar('\n');
  printf("%20s: %3d\n", "Spoiled votes", spoiled);

  return 0;
}

Given the sample data, with the quote in Mr O'Rielly's name modified from UTF-8 to ASCII, the output is:

    Arthur Smith:  17
   Sean O'Rielly:  21
   Michelle Dawn:  33
      John Brown:  36
    Robert Bloom:  39
    Michael Hall:  40
      Carl White:  64

   Spoiled votes:  77

Clearly, "Spoiled votes" is the duly elected winner.



回答2:

In order to read strings from file, you need to use fgets rather than fscanf since fgets reads the whole string. So reading of strings should look like:

int main()
{
    int i = 0;

    // initialize everything to zeroes
    // otherwise they should be initialized manually in a loop
    struct candidates electionCandidate[7] = {0}; 
    FILE *file = fopen("elections.txt", "r");
    for (i = 0; i<7; i++)
    {
        char * res = fgets(electionCandidate[i].name, 100, file);

        printf("%s\n", res);
    }

    //strcpy(electionCandidate[0].name, "Daniel Guzman");
    //electionCandidate[0].votes = 41;

    //printf("%s got %d Votes\n\n", electionCandidate[0].name, electionCandidate[0].votes);

    system("pause");

    return 0;
}

Reading the votes and counting will look like this:

while (!feof(file))
{
    int iVoteFor = 0;
    fscanf(file, "%d", &iVoteFor);
    electionCandidate[iVoteFor-1].votes++;
}

I believe it's easy to find the winner afterwards.



标签: c arrays struct