【问题标题】:perror generating unexpected errno valueperror 生成意外的 errno 值
【发布时间】:2011-02-11 22:22:53
【问题描述】:

在将perrorglibc 一起使用时,我遇到了意外的errno 值。当一个不存在的文件被指定为arg[1] 时,它会按预期打印Error: 2(即ENOENT)。但是,当下面的 perror 行未注释时,无论我通过什么,它都会引发错误 22 (EINVAL)。谁能解释一下为什么会这样设置?

编辑:看起来这是某种 Eclipse 错误。 IDE 似乎导致 perror 引发某种错误,该程序在命令行上完美运行,并且当在 Eclipse 的参数列表中指定正确的文件时完美运行。在 Eclipse 中运行时会错误地失败。

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
int main(int argc, char *argv[]) {
FILE *input_file;
input_file = fopen(argv[argc - 1], "r");
if (!input_file) {
 // perror(argv[argc-1]);
    fprintf(stderr, "Error: %d\n", errno);
    return (EXIT_FAILURE);
}
else {
    fclose(input_file);
}
return (EXIT_SUCCESS);
}

【问题讨论】:

  • 你是说 perror() 调用打印了错误的东西,还是说 fprintf 如果你调用 perror() 打印了错误的东西?
  • 两者都不是。我是说 perror 以一种意想不到的方式设置 errno。
  • @谁保证过 perror 会对 errno 造成什么影响?为什么同时调用 perror 并打印 errno?请参阅下面的 rlibby 的答案(做个好人并接受它)。

标签: c glibc errno


【解决方案1】:

在调用其他库函数后不能依赖errno 的值,也就是说你调用perror() 本身可能会修改errno 的值你需要将它保存在一个临时变量中如果您希望在调用其他库过程后能够使用它。

if (!input_file) {
    int err = errno;
    perror(argv[argc-1]);
    fprintf(stderr, "Error: %d\n", err);
    return (EXIT_FAILURE);
}

【讨论】:

  • 对,有一条规则“库调用后errno 的值是不可预测的”。有人可能认为库调用 perror 的规则应该有一个例外,但实际上 POSIX 并不能保证这一点。
  • perror 打印了错误,对于大多数人来说,这就是它的结束;保留errno将是一种浪费。我自己总是使用 strerror,从不使用 perror,这是古老且不灵活的。
【解决方案2】:

您的程序在这里按预期运行:

$ ./app fkjhsf
Error: 2

并且 perror() 呼叫未注释:

$ ./app asdkfljh
asdkfljh: No such file or directory
Error: 2

也许perror() 电话会因某种原因改变您的errno?您使用的是什么操作系统/编译器/库版本?

【讨论】:

  • Ubuntu 10.10 gcc 版本 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5)
【解决方案3】:

他很可能在没有任何参数的情况下运行程序。

如果是这样,“argv[argc - 1]”将评估为垃圾。

应该有代码确保“argc-1”在有效范围内。

【讨论】:

  • 我不是,当一个正确的文件被传递到参数列表中时它运行良好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-29
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多