【问题标题】:What's the correct way to convert an argument passed to a program to a long double variable?将传递给程序的参数转换为长双精度变量的正确方法是什么?
【发布时间】:2013-01-11 05:04:03
【问题描述】:

我遇到了这个问题...它可以编译,但是在运行时会立即出现段错误...使用 GDB,我确定它在尝试启动长双精度时会出现段错误。我觉得 atoi 可能是使用错误的函数,但我尝试了其他类似的函数,但仍然出现段错误。

int main(int argc, char *argv[]) {
  long double x = atoi(argv[1]);
  char oper = argv[2][0];
  long double y = atoi(argv[3]);

【问题讨论】:

  • 您应该在使用参数字符串之前检查您是否拥有argc >= 4。您的分段错误很可能是因为您的参数列表没有您想象的那么长。如答案所述,atoi() 用于将字符串转换为整数; strtold() 适用于 long double

标签: c linux arguments command-line-arguments argument-passing


【解决方案1】:

atoi() 代表“ascii to integer”,这不是你想要的。你应该使用一个合适的函数——strtold(3) 是最合适的,但你也可以使用sscanf(3)

【讨论】:

    【解决方案2】:

    将字符串转换为long double的正确方法是

    long double strtold(const char *nptr, char **endptr);
    

    【讨论】:

      【解决方案3】:

      使用strtold:

      #include <stdlib.h>
      #include <errno.h>
      
      char * e;
      errno = 0;
      long double d = strtold(argv[1], &e);
      
      if (*e != 0 || errno != 0) { /* Error! Do not consume the result. */ }
      
      // result now in "d"
      

      您可以使用*e 的值来判断字符串的任何部分是否被消耗;有关详细信息,请参阅手册。我的示例只是检查是否可以解析 整个 字符串。

      我实际上不确定是否有线程安全的解决方案......(哦,我想是的,因为errno 是线程本地的。)

      【讨论】:

      • 好的...我在使用第二个参数时遇到了问题。如何确定争论的结束?传递的参数是简单的等式,例如 1+1,但每个数字的字符长度可以是合理范围内的任意位数。
      • +1 用于提及 errno 检查(如果您希望检查有意义,则必须在调用函数之前将 errno 设置为 0)。我不知道strtolstrtollstrtodstrtold 可能会返回错误,但仍会返回结果。我写的代码只检查if (*e != 0)
      • 在这种情况下,您将需要编写一个(合理的)解析器,因为1.01212131+31.1212121*9.12/11.991 将被视为一个参数。另一方面,如果你用空格分隔事物,你可以只使用argv[],所以1.01212131 + 31.1212121 * 9.12 / 11.99 将是7 个不同的参数。
      • errno 检查相当没用,因为strtold 可能遇到的唯一“错误”是上溢/下溢,对于浮点来说,这只是“严重舍入”,可能不是您想要的视为错误。检查endptr 涵盖了所有真正的错误情况(格式错误的输入)。
      • @R..:不过,上溢和下溢有用的错误。当你解析整数时,它们甚至更有用(在这种情况下,你真的不能消耗解析的结果),我想在这里鼓励一种模式。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-23
      • 2020-05-23
      • 2019-01-27
      • 1970-01-01
      • 2015-09-20
      • 2016-06-07
      • 1970-01-01
      相关资源
      最近更新 更多