C - 使用 scanf 问题查找最大、最小和平均值

标签 c stdin scanf

我一直在努力寻找一些问题的解决方案,这些问题确实是 C 编程类(class)的基本作业。其中最简单的我会在这里寻求帮助;我花了这么长的时间来解决这个问题,这表明我不理解某些概念。

该任务让我读取浮点值直到 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;
}

我的代码能够处理格式良好的输入,但有一个问题:标记方案将测试我的程序对空白行的 react ,而空白行将被忽略。仅当每个输入都遵循指定的 %f\n 格式时,我的代码才能正常工作,并且如果存在空行,则打印不正确的输出(或者我可能完全错误,并且其他地方根本上有问题)。

我尝试了一些适用于其他作业的解决方案,例如字符串输入情况下的分隔符。这是我能想到的最好的办法,而且确实有效;再说一遍,只有在有空行的情况下才会失败,而且我不知道有空行时到底出了什么问题。

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

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 返回来在一定程度上限制这一点,但这并不是一个完整的解决方案。不要使用 scanf 读取离散 float ,而是使用 fgets 读取整行。正如您所描述的输入文件,每行有一个浮点值(或者没有或垃圾)。这提供了使用 strtof 转换每一行的完美场景。检查 strtof 的返回结果,您要么在线上有 float ,要么没有,这样您就可以轻松处理空白行或垃圾行。

此外,为了计算最小最大平均值,没有理由在程序持续时间内存储每个值。读取每个,将值添加到total,增加count,并测试当前是否是新值最少最大然后继续。无需存储。

以下是从 stdin 读取 float 并将其处理为您想要的值的简短示例:

#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

关于C - 使用 scanf 问题查找最大、最小和平均值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29786430/

相关文章:

c - 使用 stat (st_uid) 的段错误(核心转储)

batch-file - 如何在 Windows 命令行中将标准输入重定向到文件?

php - 如何通过 proc_open 后台进程并访问 STDIN?

c - scanf 函数是否会导致运算符出现任何逻辑问题?

通过 c 中的用户输入创建字符串数组?

c - 为什么将数组转换为指针的规则中缺少 _Alignof?

c - O_NOBLOCK 标志是否会使文件 write() 失败,在什么情况下?

c - Linux 管道不良行为

perl - 阅读文本的好方法是什么?

c - 如何中断使用 fgets()、使用 scanf ("%s"读取的字符串,..)