C:如何使用strtok从输入文件输出等级&找到平均值,最小值和最大值?

时间:2015-03-17 00:48:55

标签: c strtok text-parsing

我尝试从输入文件中输出作业等级,并输出每个作业的平均成绩,最低成绩和最高成绩。

例如,具有4名学生和3个作业的班级的输入文件可能如下所示:

8.5, 10.5, 90.5
49.5, 99, 97
88, 88, 100
88.5, 99, 0

,输出应为

Student grades from the input file:
8.5, 10.5, 90.5
49.5, 99.0, 97.0
88.0, 88.0, 100.0
88.5, 99.0, 0.0

Assignment # 1 stats
avg = 58.6
min = 8.5
max = 88.5

Assignment # 2 stats
avg = 74.1
min = 10.5
max = 99.0

Assignment # 3 stats
avg = 71.9
min = 0.0
max = 100.0

到目前为止,我已经停留在第一部分,我必须输出文件的内容。这就是我到目前为止,对此或功能的任何帮助将不胜感激。

int main(int argc, char *argv[]) {
    FILE *input_file;
    int line_number = 0;
    char *next_field;
    char line[MAX_STUDENTS+1];

    input_file = fopen(argv[1], "r");

    //OUTPUT THE GRADES FROM THE INPUT FILE
    while (1) {
        fgets(line, MAX_STUDENTS, input_file);
        if (feof(input_file))
            break;

       next_field = strtok(line, " \n");


    while (next_field != NULL) {
            printf("==================================/n");
            printf("Student grades from the input file/n");
            printf("==================================/n");
            printf("%s,", next_field);

            next_field = strtok(NULL, " \n");
        }
    }

1 个答案:

答案 0 :(得分:0)

您可以像这样标记和输出:

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

#define MAX_LINE_LEN 1024

int main(int argc, char **argv) 
{
  int   line_number = 0;
  FILE *input_file;
  char  line[MAX_LINE_LEN + 1];
  char *next_field;
  char *end_field;

  if (1 == argc)
  {
    fprintf(stderr, "usage: %s <filename>\n", argv[0]);
    exit(1);
  }

  if (NULL == (input_file = fopen(argv[1], "r")))
  {
    perror(argv[1]);
    exit(1);
  }

  fprintf(stdout, "Student grades from the input file:\n");

  while (fgets(line, sizeof(line), input_file))
  {
    int first = 1;

    ++line_number;

    for (next_field = strtok(line, ",\n"); NULL != next_field; next_field = strtok(NULL, ",\n")) 
    {
      errno = 0;

      double grade = strtod(next_field, &end_field);

      if (errno || end_field == next_field || *end_field)
      {
        fprintf(stderr, "Warning: malformed input '%s'? Skipping!\n", next_field);
        continue;
      }

      fprintf(stdout, "%s%.1lf", (first ? "" : ", "), grade);
      first = 0;

      // TODO: store grade (or at least running min, max, avg) in a structure that stores assignments stats for later processing and printing
    }

    if (!first)
      fprintf(stdout, "\n");
  }

  return 0;
}

您需要在某种结构中存储有关每个作业的统计数据,以便在阅读完所有输入后打印出作业统计数据。

请注意,我使用&#34;,\ n&#34;来呼叫strtok而不是&#34; \ n&#34;因为我相信逗号真的是你输入中的重要分隔符。至少,对于.csv文件来说,这通常是正确的,这是用于分隔要处理的数据的通用格式。

请注意,我们的两种方法都会对不同类型的输入做一些令人担忧的事情。例如,如果一行看起来像"7.0,8.0,9.0,10.0\n",那么您的标记化将无法正常工作,这在.csv文件中很常见。您的程序可能只处理7.0并忽略其余部分。您的程序也可能不会像"7.0,HiThere 8.0, 9.0\n"那样反对输入。然后,您的程序可能会像"7.0 8.0 9.0, 10.0\n"一样处理"7.0, 8.0, 9.0, 10.0\n",即使前一个字符串中缺少一些逗号。是好还是坏?答案取决于您的输入文件格式以及您希望其结构的严格程度。对于前一个字符串,我的标记化方法会反对原始输入中的7.0',''\n'没有立即跟踪'\0',但允许空格在一个数字开始之前,这是一个有点奇怪的对空白的不对称处理。它也会轻率地处理"7.0,,,,10.0\n",甚至没有注意到&#34;缺失&#34;在线上的字段。

所以,你需要弄清楚你想要的挑剔程度以及你在程序中想要的错误处理能力。