计算给定字符串的浮点数的长度

时间:2015-07-17 10:20:03

标签: c string floating-point char converter

假设您有一个变量char s[30],并且s以正浮点数开头,例如 s = "15.016This is not a part of the float !";

浮动之后的角色可能只是一个数字。

目标是确定浮点数表示的字符数,例如| 15.016 | = 6.

我正在尝试编写一个简单的代码,最好没有任何外部库。

我有:

int count_len(char *s)
{
   char tmp_buf[30];
   int integral_digits = sprintf(tmp_buf, "%d", atoi(s) );
   return integral_digits + sprintf(tmp_buf, "%d", atoi(s + integral_digits +1) );
}

这适用于分数不包含前导零的任何数字(适用于15.16,但不适用于15.016)。

你将如何修复这个功能?

8 个答案:

答案 0 :(得分:4)

为什么不简单地将sscanf与adhoc格式说明符一起使用?

考虑

sscanf("15.01336This is not a part of the float !", "%*f%n", &len);

%*f%n表示

  • %*f读取一个的浮动数字,但不要将其存储在任何地方,只需使用它。
  • 到目前为止,
  • %n存储了消费字符数

一个工作示例

#include <stdio.h>

int main()
{
    int len;

    sscanf("15.01336This is not a part of the float !", "%*f%n", &len);

    printf("%d\n", len);

    return 0;
}

答案 1 :(得分:2)

C是黑客攻击,所以为什么不动态编写你的函数,例如:

size_t floatlenghth(char *s)
{
  size_t len = 0;
  short found_dot = FALSE;
  while ((*s >= '0' && *s <= '9') || (*s == '.' && !found_dot)) {
    len += 1;
    if (*s == '.') found_dot = TRUE;
    s++;
  }
  return len;
}

让事情变得复杂,

  • 您必须查看区域设置(如','表示小数分隔符)。

    .... char dottype = getdottypeforlocale();

    .... if(* s == dottype)

  • 你想如何计算一个点后的前导零和尾随零(f.e。“001.200blubber”是长度为7还是长度为3?)

    ... s = skipleadingzeros(s);

    在 / if(found_dot&amp;&amp; * s =='0')counttrailingzeros ++中,

    ... / 在里面别counttrailingzeros = 0;

    / len - = counttrailingzeros;

  • 之后

    ... /

  • 科学记数法:1.22E01

    ...在while()之后看看iff * s ='E'并且接下来的两个字符是数字,然后加3

  • thousender-mark(s),如1'234.56(这在哪里有效?)或1,234.56(英文)或1.234,56(德文)或1,234,567.89

答案 2 :(得分:1)

如果你有一个模式的输入字符串,

  "15.016This is not a part of the float !";

正如您在问题中提到的,我建议您使用string.h中提供的strspn()strcspn()功能来查找长度float类型的>。

如果您使用strspn(),则可以将accept设置为所有数字并点.

您不需要外部库来使用它们。它们是标准Cglibc的一部分。

答案 3 :(得分:1)

int count_len(char *s){
    int len = 0;
    sscanf(s, "%*lf%n", &len);
    return len;
}

答案 4 :(得分:1)

strtod非常适合:

char *endOfFloat;
double val = strtod( str, &endOfFloat );
size_t len = (size_t) endOfFloat - str;

这假设字符串的float部分格式正确,可表示为double

如果情况并非如此,那么您需要采用不同的方法。

答案 5 :(得分:0)

我在3分钟内写完了这篇文章。它有几个错误,例如,它在数字的右侧计为零。这是你可以自己解决的问题:)

int count_len(const char *s)
{
    const int sz = strlen(s);
    int sz_of_float = 0;
    bool dot = false; // to avoid double dots like ".."
    for(int i = 0; i < sz; i++)
    {
        if(s[i] >= '0' && s[i] <= '9')
            sz_of_float++;
        else if(s[i] == '.' && dot == false)
        {
            dot = true;
            sz_of_float++;
        }
        else
            return sz_of_float;
    }
    return -1;
}

答案 6 :(得分:0)

以下是如何考虑编写此类函数的算法。

  1. 将计数设置为零。
  2. 如果第一个字符是非零数字,请将计数设置为1.否则,退出并返回零。
  3. 从下一个字符开始,在点击非数字字符或字符串结尾之前读取最大位数,每次都递增计数。
  4. 如果到达字符串的结尾,请退出并返回计数。否则,如果字符是句点,则将计数加1。
  5. 从句点后的下一个字符开始,在点击非数字字符或字符串结尾之前读取最大位数,每次都增加计数。
  6. 返回计数。
  7. 示例代码:

    int countDigits(char const * str)
    {
        int count = 0;
        int i;
    
        if (str == NULL) return 0;
        for (i = 0; str[i] != '\0'; i++) {
            if (isdigit(str[i]))
                count++;
            else
                break;
        }
    }
    
    int countFloatChars(char const * str)
    {
        int count = 0;
    
        if (str == NULL) return 0;
        if (str[0] == '\0') return 0;
    
        if ((str[0] < '1') || (str[0] > '9')) return 0;
    
        count = 1;
        count += countDigits(str + count);
    
        if ((str[count] == '\0') || (str[count] != '.')) return count;
    
        count++;
        count += countDigits(str + count);
    
        return count;
    }
    

答案 7 :(得分:0)

不使用C库,寻找至少找到1位数的(digits).(digits)

size_t float_length(const char *s) {
  const char *p = s;
  int digit_count = 0;

  // could add tests for white-space, +, - here        

  while (*p >= '0' && *p <= '9') {
    s++;
    digit_found = 1;
  }
  if (*p == '.') {
    p++;
    while (*p >= '0' && *p <= '9') {
      p++;
      digit_found = 1;
    }
  }
  if (digit_found) return (size_t) (p - s);
  return 0;
}

没什么特别的。