【问题标题】:Store doubles in an array in C将双精度数存储在 C 中的数组中
【发布时间】:2019-06-19 23:04:20
【问题描述】:

我真的需要帮助将双精度值存储在双精度数组中。我正在尝试使用 scanf_s 并且它有效。但是如果我尝试输入超过 4 个值,我的程序会崩溃并返回错误代码 3

我实际上需要一个动态数组,但是因为我遇到了太多错误,所以我改变了,我尝试使用一个通用数组,这样我至少可以为这个项目获得一些分数。

这是我现在使用的代码...

int main()
{
    printf("Enter white-space separated real numbers. Terminate input with ^Z\n");
    //get the dynamic array

    double numSet[1000] = { 0 };
    int size = 0;
    double number;
    while (scanf_s("%lf", &number) == 1)
    {
        numSet[size] = number;
        size++;
    }


    //sort the array using qsort 


    //range of the array 

    double min = numSet[0];
    double max = numSet[size - 1];


    //get the mean 
    double sum = 0.0;
    for (size_t i = 0; i < size; i++)
    {
        sum += numSet[i];
    }

    double mean = sum / size;



    printf("Range: [%.2f ... %.2f]\n", min, max);
    printf("Arithmetic mean is: %f", mean);



}

我有两个问题:

  1. 是关于缓冲区溢出的警告:

    Warning C6385   Reading invalid data from 'numSet':
    the readable size is '8000' bytes, but '-8' bytes may be read.  
    
  2. 当我尝试输入超过 4 个数字时,我的程序崩溃并返回代码 3

【问题讨论】:

  • 你确定 size>0 当你做 double max = numSet[size - 1]; ?或者更一般地说,这就是所有代码吗?你是怎么做qsort的?
  • 请注意,如果在 Unix 上运行,点击 ^Z (control-Z) 将使您的程序进入暂停状态并让 shell 再次控制 - 而不会实际终止程序。在 Windows 上,输入 ^Z 表示 EOF。
  • 在引用数组中的(可能不存在的)数据之前,您不会检查 size 是否至少为 1。这是编译器的警告。 ——我看到你删除了一段代码sort the array using qsort。您显示的代码是否崩溃,或者只有您未显示的代码? (排序不一定是错的,但不需要得到minmax。)
  • 您是否需要使用数组?如果不需要数组,则您的程序远比必要的复杂。您的输入循环可以简单地累积所有输入值的总数,计算输入值的数量,并确定输入的最小值和最大值。
  • 我看到的唯一错误是 1) 可能的缓冲区溢出(您在声明需要动态数组时已经承认)可以通过将循环条件更改为“修复”:@987654330 @,以及 2) size 为 0 时的各种错误,例如 a) 索引 -1 处的无效数组访问,因为编译器警告您,以及 b) 除以 0。

标签: c arrays dynamic


【解决方案1】:
while (scanf_s("%lf", &number) == 1)
    {
        numSet[size] = number;
        size++;
    }

而不是这个用途

while (scanf_s("%lf", &number) == 1 && size <= 1000)
    {
        numSet[size] = number;
        size++;
    }

您的循环无限循环,因为它没有终止字符。 scanf_s 仅从键盘读取值,并有另一个参数来设置其最大输入缓冲区值,这对限制您的输入很有用。

您可以做的是在让用户输入值之前从用户那里读取大小,或者您可以每次询问用户是否要向数组添加更多值。

例如:

char option = 'Y';
while ( (scanf_s("%lf", &number) == 1 && option == 'Y'){
   // code to enter a new number
   printf("Do you want to add more numbers? (Y/N) ");
   scanf("%c", &option);
}

另外,scanf_s 函数返回扫描的值的数量,每次都是 1,因为您总是取一个双精度值。

所以即使你把它去掉,也不会有太大的麻烦。

【讨论】:

    【解决方案2】:

    我认为问题在于您如何结束输入循环,不需要 scanf_s,请查看监视窗口。我只是将结束条件更改为一些无数字字符。

    Code::Blocks 观察窗口

    【讨论】:

      【解决方案3】:

      如 cmets 中所述,有可能

      double max = numSet[size - 1];
      

      评估为

      double max = numSet[-1];
      

      size = 0。我猜double 是 8 字节宽,所以编译器警告它可能会尝试从内存中读取 -1 * 8 = -8 字节。

      【讨论】:

      • 查看scanf_s() 的 MS 手册页表明,您的“额外参数”想法对于 double 是错误的(它显示了在没有额外参数的情况下使用 float 的示例,并且评论说与字符串相关的转换说明符需要长度 - 而不是数字说明符。'这很有趣,因为我们链接到几乎相同的 URL,但得出相反的结论。
      • @JonathanLeffler,您似乎比我更仔细地阅读了文档。它说“指定所有 c、C、s、S 或字符串控制集 [] 参数的大小”,但没有提及正如你所建议的,数字类型。谢谢!
      猜你喜欢
      • 2011-08-05
      • 2017-10-26
      • 1970-01-01
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      • 2019-07-13
      • 2015-07-23
      • 1970-01-01
      相关资源
      最近更新 更多