【问题标题】:C - Finding greatest, least, and mean with scanf problemsC - 使用 scanf 问题查找最大、最小和均值
【发布时间】:2015-04-22 02:03:35
【问题描述】:

我一直在努力寻找一些问题的解决方案,这些问题无疑是 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 格式时,我的代码才能正常工作,并且如果有空行(或者我可能完全错了,而其他地方根本有问题),则打印不正确的输出。

我尝试了一些适用于其他分配的解决方案,例如字符串输入中的分隔符。这是我能想到的最好的方法,它确实有效;同样,只有在有空行时才会失败,并且我不知道有空行时到底出了什么问题。

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

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;

这是一个替代版本的主体,我已经使用了更多可能更误导的使用内存分配给缓冲区。然而,这个版本的段错误我只能假设是我如何接收和存储输入;问题仍然存在。

【问题讨论】:

  • while (buffer[x] != EOF)。对于初学者来说,这看起来是错误的。 buffer 在您第一次点击 while 循环时被统一化(甚至对于一些后续迭代)。不知道你想在那里做什么。
  • 你说得对,这是我最接近成功的代码版本;我想我已经修复了那个,但我确保至少将某些东西扫描到缓冲区中,以便循环运行。我已确保将 x++ 改进移出,因此如果出现问题,它不会在该 while 条件下无限循环。感谢您的额外关注!
  • 请发布一个包含所有内容的版本。谈论当前发布的版本并不好,因为它没有超过一垒。

标签: c stdin scanf


【解决方案1】:

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

此外,为了计算 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

【讨论】:

  • 我可能从来没有尝试过使用 fgets,因为我一直怀疑我使用 fgets 的能力,因为它接收到 char* 并且我想我会打开一个新的蠕虫罐试图以不同的方式投射。非常感谢你也让我知道 strtof,这正是我在这种情况下所需要的,但我的大脑功能库还没有完全填满。
  • 很高兴能提供帮助,这就是我们学习的方式。读取一行时除了fgets,还要考虑getline(它为你分配空间并返回实际读取的字符数)。 99% 的情况下,如果您从多行读取值,则读取整行然后解析输入是正确的方法。祝你好运。
猜你喜欢
  • 1970-01-01
  • 2014-06-11
  • 1970-01-01
  • 2015-01-16
  • 1970-01-01
  • 1970-01-01
  • 2021-01-24
  • 2016-12-29
  • 1970-01-01
相关资源
最近更新 更多