【问题标题】:Read user input and modify an array using EOF within a function in C?在 C 中的函数中使用 EOF 读取用户输入并修改数组?
【发布时间】:2016-03-21 06:15:22
【问题描述】:

我尝试将 EOF 用于函数中的用户输入,并相应地修改数组,因此在主函数中它将是该值。我试过用谷歌搜索并阅读人们的答案,但我仍然无法让它工作..

void Get_Data(double data[], double original[], int length)
{
    int count = 0;
    double value = 0;
    printf("Enter data and Ctrl + D when you're done(Ctrl + Z for Windows): \n");

    while (scanf("%f", &value) != EOF)
    {
        data[count] = value;
        original[count] = data[count];
        count++;
    }
    printf("%f\n", data[1]);
}

int main()
{
    int i;
    double sum, original[4] = {0}, datas[4] = {0};
    Get_Data(datas, original, 4); // I'm just trying to get this to work

    system("pause");
    return 0;
}

我读到过在 C 中使用 * 在参数中通过引用传递,但我没有得到正确的结果。

【问题讨论】:

  • 第一:什么是'Fn'?第二:你期望的结果是什么,你得到的结果是什么。更多细节会有所帮助
  • 您不仅需要使用"%lf"作为格式说明符来读取double值,还需要检查您是否从scanf()返回1;如果输入中有非数字、非空格字符,您将得到 0(与 EOF 不同),并且您的程序可能会在崩溃前运行一段时间。您还应该确保不要超出函数内部 length 中的条目数 - 超出数组范围写入是“未定义行为”的不良情况。

标签: c arrays parameters scanf eof


【解决方案1】:

要扫描double 值,您需要使用%lf 格式说明符。

来自C11,第 7.21.6.2 章,

l (ell)
指定以下 diouxXn 转换说明符适用 类型指针指向long intunsigned long int 的参数;以下aAeEfFgG 转换说明符适用于 类型指针指向double 的参数; [....]

也就是说,

  1. 当您正确传递 length 时,请在您的函数中使用它来限制 count(索引)以避免超出分配的内存。

  2. 您还应该检查scanf() 是否成功(通过检查返回值与假定要扫描的项目数)。只检查 aginst EOF foes 是不够的,scanf() 也可以在匹配失败的情况下返回 0 也需要处理。

【讨论】:

  • 是的——但这不是问题中显示的代码中唯一的问题。
  • @JonathanLeffler 您是在指出scanf() 返回上最明显的成功检查还是我缺少的其他内容?
  • 既然你更新了你的回答提到length(与我看到的第一个版本相比——但你显然在5分钟的窗口内改变了它),那么是的,另一个主要问题是检查@ 987654350@ 与 == 1。我发现我使用“HTTPS Everywhere”的一个缺点是 SO 上的自动更新不再起作用了。我必须刷新才能看到更改。
  • @JonathanLeffler 对。让我也添加一些信息。
【解决方案2】:

while (scanf("%f", &value) != EOF) 更改为while (scanf("%lf", &value) == 1)

首先,要检查输入过程是否成功,您不应该使用scanf("...", ...) != EOF。想一想:如果用户输入一个字符怎么办?那么scanf()匹配失败后返回0,0 != EOF

其次,要扫描类型为double 的变量,您必须使用"%lf"。你可能会问:为什么?我可以使用"%f" 打印floatdouble

嗯,那是因为通常是sizeof (float) != sizeof (double)。假设sizeof (float) == 4sizeof (double) == 8

  • scanf() 语句中,程序必须知道要写入的内存块的长度。如果有"%f",并且0x12345678作为对应地址传递,则0x123456780x1234567C被填充,而当有"%lf",并且0x12345678作为地址传递时,内存从0x123456780x12345680 已填写。
  • 由于printf()有可变参数,float变量被隐式转换为double,然后传递。很明显,将float 转换为double 不会导致任何信息丢失,所以一切正常。

总结一下,重点是floats自动提升为doubles,但float *s并没有转换为double *

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-09
    • 1970-01-01
    • 2020-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多