【问题标题】:how do I assign values from text file to a structure of arrays in C?如何将文本文件中的值分配给 C 中的数组结构?
【发布时间】:2014-10-30 18:03:46
【问题描述】:

我必须在 C 中做一个选举程序。

共有 7 名候选人和 365 票。我需要使用一组结构来做到这一点。我需要从文本文件中读取每个候选人的姓名和他们获得的票数。最后我需要输出选举的获胜者。

到目前为止,这是我的代码示例

    #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

这是我目前的选举.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 

编辑:

每位候选人获得 +1 票,选举候选人[0] 每获得一票,其余的以此类推。共有 365 名选民。

我能够从文本文件中输入每个候选人的姓名。现在的问题是将每张选票投给相应的候选人。此外,任何高于 7 的投票都是我试图在上面的代码中计算的被破坏的投票。代码编译但它崩溃了。

我正在使用 while(!feof) 但它似乎不起作用或者这不是正确的方法。任何建议。

编辑: 我正在使用调试器,发现它在一段时间内运行了几次(!feof) 但在其中一种情况下,它会给出错误并停止。

编辑: 通过注释掉这行代码electionCandidate[iVoteFor-1].votes++;程序一直读取到 365 值。

我如何分配给每个候选人投票?

【问题讨论】:

  • 请不要使用void main(),即使在支持它的Windows 上也是如此。正确的返回类型是int,在C89系统(比如微软的编译器)上,应该在main()的末尾加上return 0;
  • 您需要添加FILE* btw的名称
  • 1) 22fgets(electionCandidate[i].name, 22, fp);sizeof electionCandidate[i].name == 20 时? 2)不要使用feof(),使用fscanf()的返回值。 3) 代码没有测试被破坏的选票。
  • 代码对while (!feof(fp)) { ...} 做了一个很大的否定。 fscanf() before feof() 变为 true 未能读取任何选票,因此 iVoteFor 保持为 0。代码不进行范围检查,然后继续执行 electionCandidate[0-1].votes++; 之外的 electionCandidate[] --> 哎呀。好奇:使用feof() 建议参考什么?
  • !feof 不会读取我正在读取的整个文件的内容吗?我在另一篇文章中看到了这个

标签: c arrays struct


【解决方案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;
}

给定示例数据,将 O'Rielly 先生名字中的引号从 UTF-8 修改为 ASCII,输出为:

    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】:

    为了从文件中读取字符串,您需要使用 fgets 而不是 fscanf,因为 fgets 会读取整个字符串。所以字符串的读取应该是这样的:

    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;
    }
    

    读取选票和计票将如下所示:

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

    我相信之后很容易找到赢家。

    【讨论】:

    • 我不太明白您的electionCandidate[iVoteFor].votes 是如何在这里工作的,因为每个候选人都有一个与之相关的数字,例如“1”数字表示我正在投票给我的第一个列表。这是怎么告诉它的。
    • 好的。有一个错误。现在是electionCandidate[iVoteFor-1].votes++,意思如下。关联的数字是候选人的索引,所以你取记录,对应候选人索引,获取该索引的投票数(初始化后为0)并用运算符++将其增加为1;
    • "1" 数字表示我正在投票给我列表中的第一个,所以这是第一条记录。但是,C 从 0 开始计数,这就是为什么要使用“iVoteFor-1”索引。
    • 线路选举候选人[iVoteFor-1].votes++;当我输入这一行时,它会显示正确的输出,但程序崩溃了我一直试图以不同的方式对其进行格式化,但我的程序崩溃了
    • while (!feof(file)) ... 的使用是错误的。使用返回值形式fscanf()
    猜你喜欢
    • 2011-05-24
    • 2020-12-20
    • 1970-01-01
    • 1970-01-01
    • 2013-11-20
    • 1970-01-01
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    相关资源
    最近更新 更多