C - 使用 scanf 问题求最大、最小和均值

C - Finding greatest, least, and mean with scanf problems

我一直在努力寻找一些问题的解决方案,这些问题诚然是 C 编程课程的基本作业。我将在这里寻求最简单的帮助;我处理它的时间长度表明我不理解某些概念。

任务让我读取浮点值直到 EOF,用换行符分隔;我的程序是获取这些值并记录最大值和最小值,并计算平均值并以特定格式打印它们。

#include <stdio.h>
#include <math.h>
#include <ctype.h>

int main()
{
    float buffer[200];
    float least, greatest = 0, mean = 0;
    float total = 0, count = 0;
    int x=0, y = 0;
    while (buffer[x] != EOF)
      {
        y = scanf("%f\n", &buffer[x]);
        if (y == 1)     
        {
            if (isspace(buffer[x])==0)
            {
                if (x == 0) {least = buffer[x];}

                if(buffer[x]>greatest) {greatest = buffer[x];}

                if(buffer[x]<least) {least = buffer[x];}

                total += buffer[x];
                count++;
                x++;
            }
        }
      }
    mean = total/count;
    printf("%.2f ", least);
    printf("%.2f ", greatest);
    printf("%.2f\n", mean);

    return 0;
}

我的代码能够处理格式正确的输入,但有一个转折:标记方案将测试我的程序对空行的反应,这些空行将被忽略。仅当每个输入都遵循指定的 %f\n 格式时,我的代码才能正常工作,如果有空行则打印不正确的输出(或者我可能完全错了,其他地方根本就出了问题)。

我试验了一些对其他作业有效的解决方案,例如字符串输入中的定界符。这是我能想到的最好的办法,而且确实有效;再次,它只有在有空行时才会失败,我不知道有空行时到底出了什么问题。

感谢阅读这些文字墙!这是我的第一次 post,我不确定我是否粗鲁、过于自私,或者没有提供足够的关于我的案件的信息。

float* buffer;
float least, greatest = 0, mean = 0;
float total = 0, count = 0;
int x=0, y = 0;
buffer = (float*)malloc(200 * sizeof(float));
y = scanf("%f\n", &buffer[x]);
if (y == 0)
{
    return 1;
}
while (buffer[x] != EOF)
  {
    y = scanf("%f\n", buffer[x]);
    if (y == 0)
    {
        x++;
        continue;
    }
    if (isspace(buffer[x])==0)
    {
        if (x == 0) {least = buffer[x];}

        if(buffer[x]>greatest) {greatest = buffer[x];}

        if(buffer[x]<least) {least = buffer[x];}

        total += buffer[x];
        count++;

    }

    x++;
  }
mean = total/count;
printf("%.2f ", least);
printf("%.2f ", greatest);
printf("%.2f\n", mean);

return 0;

这是主体的替代版本,我曾更多地使用它可能更误导地使用缓冲区的内存分配。但是,由于我只能假设的原因,这个版本的段错误与我接收和存储输入的方式有关;问题仍然存在。

您处理问题的方式使得处理输入文件中的变化变得困难。虽然您可以通过检查 scanf return 在某种程度上限制这一点,但这不是一个完整的解决方案。与其使用 scanf 读取离散的浮点数,不如使用 fgets 读取整行。正如您所描述的输入文件,每行有一个浮点值(或没有或垃圾)。这为使用 strtof 转换每一行提供了一个完美的场景。检查 strtof 的 return 行上是否有浮点数,从而使您可以轻松处理空白行或垃圾行。

此外,要计算 leastgreatestmean,没有理由在程序运行期间存储每个值。读取每个 value,将值添加到 total,递增 count,并测试当前的 value 是新的 least 还是 greatest 和继续。无需存储。

这是一个从 stdin 读取浮点数并将其处理为您想要的值的简短示例:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>

#define MAXL 200

int main()
{
    float value = 0.0;
    float least = (float)(INT_MAX);
    float greatest = (float)(-INT_MAX - 1);
    float mean = 0.0;
    float total = 0.0;
    size_t count = 0;
    char buffer[MAXL] = {0};

    while (fgets ( buffer, MAXL - 1, stdin) != NULL)
    {
        char *ep = buffer;
        value = strtof (buffer, &ep);
        if (errno == 0 && (ep != buffer && value != 0.0))
        {
            least = value < least ? value : least;
            greatest = value > greatest ? value : greatest;
            total += value;
            count++;
        }
    }

    mean = total/count;

    printf("%.2f ", least);
    printf("%.2f ", greatest);
    printf("%.2f\n", mean);

    return 0;
}

输入

$ cat dat/float.dat
100.3
dogfood

300.1
The quick brown fox jumped over the lazy dog.


12.0

400.4

输出

$ ./bin/read_float_lines < dat/float.dat
12.00 400.40 203.20