【问题标题】:Find out constant value by given string in c通过c中的给定字符串找出常量值
【发布时间】:2011-06-22 06:43:42
【问题描述】:

需要检查给定的字符串是否为常量值(int/long/double)?

这里使用strtol函数来查找常数值。但面临问题

例子:

   if(li1 = strtol (str,NULL,0))
       printf("valid Integer ...");
  1. str = "1" 输出 = 1.00
  2. str = "0.99999" 输出 = 0.00
  3. str = "tab" 输出 = 0.00

那么如何通过查看输出来区分“0.99999”和“tab”呢?

【问题讨论】:

  • 如果您可能要处理浮点数,为什么不strtofstrtod

标签: c string


【解决方案1】:

对于整数,strtol 提供第二个参数,该参数将被设置为指向第一个不可转换的字符。

如果它是空终止符\0 以外的任何内容,则数字末尾有垃圾。如果它等于原始字符串,则 no 找到合适的字符。

例子:

char *str = "72";

char *estr;
float val = strtol (str, &estr, 10);
if (estr == str) {
    // there was no convertible characters.
}
if (*estr != '\0') {
    // there was rubbish at the end.
}
if (errno != 0) {
    // underflow/overflow.
}

对于浮点,您需要使用strtoX 函数之一。

它的作用与strtol 函数非常相似。

示例用法:

char *str = "0.9999";

char *estr;
float val = strtof (str, &estr);
if (estr == str) {
    // there was no convertible characters.
}
if (*estr != '\0') {
    // there was rubbish at the end.
}
if (errno != 0) {
    // underflow/overflow.
}

下面的完整程序显示了一个计算字符串表示的类型的函数:

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>

#define TYP_INTEGRAL 0
#define TYP_FLOATING 1
#define TYP_BAD      2
int getTypeAndData (char *str, long *valL, float *valF) {
    char *end;

    *valL = strtol (str, &end, 10);
    if ((end != str) && (*end == '\0'))
        return TYP_INTEGRAL;

    *valF = strtof (str, &end);
    if ((end != str) && (*end == '\0'))
        return TYP_FLOATING;

    return TYP_BAD;
}

int main (int argc, char *argv[]) {
    char *desc[] = {"INT", "FLT", "BAD"};
    int i, typ;
    long lvar;
    float fvar;
    for (i = 1; i < argc; i++) {
        lvar = 0; fvar = 0;
        typ = getTypeAndData (argv[i], &lvar, &fvar);
        printf ("%s: [%-10s] %10ld %10.3f\n", desc[typ], argv[i], lvar, fvar);
    }
    return 0;
}

使用myprog 12345 hello 12.7 1e2 0.4 .1 "" 0 运行时,输出为:

INT: [12345     ]      12345      0.000
BAD: [hello     ]          0      0.000
FLT: [12.7      ]         12     12.700
FLT: [1e2       ]          1    100.000
FLT: [0.4       ]          0      0.400
FLT: [.1        ]          0      0.100
BAD: [          ]          0      0.000
INT: [0         ]          0      0.000

您可以看到它至少检测到了我可以快速提出的单元测试用例。

请注意,这并不直接传达下溢和上溢条件。在这些情况下会返回默认值,因为它们通常是明智的选择,但如果您想捕捉这些条件,可以在返回后查看errno

【讨论】:

  • 我希望我能 +2 - 一个用于出色的帖子,另一个用于“湿件”一词。
  • 在前两个中,您可能需要根据特定值检查errno,以确保它不是仍然从以前的函数中设置的(尽管我想如果它是调用者应该已经处理了错误并且手动重置?)
  • 感谢您的回复。但它不适用于以下测试用例 1. 10L ===> 浮动常量 2. 10xyz ===> 不是常量
  • @ashwini,这是因为根据strtoX 规则,10L 不是有效的整数或浮点数(尽管它在 C 源代码中有效)。如果您想接受strtoX 范围之外的有效数字,您的代码将会复杂得多。这是可行的,但不能单独使用这些函数(最好的办法是预先按摩字符串以删除尾随的L/LL/UL/ULL/etc). I would suggest opening up a separate question asking for a function that does that (and specifying _everything_ you need). As for 10xyz`,即使作为 C 中的常量也是无效的,所以我不确定你为什么想要接受这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-19
  • 2019-04-14
  • 1970-01-01
相关资源
最近更新 更多