【问题标题】:Split float from beginning of string in C从C中的字符串开头拆分浮点数
【发布时间】:2021-03-14 21:41:39
【问题描述】:

我目前正在用 C 编写一个可以标记算术表达式的程序,但我在这里只提供了一个最小的、可重现的示例。

以下代码成功将-5.2foo拆分为-5.2foo

#include <stdio.h>

int main(void)
{
    char str[] = "-5.2foo";
    float f;
    sscanf(str, "%f%s", &f, str);
    printf("%f | %s\n", f, str);
    return 0;
}

但是如果字符串只包含一个浮点数(例如-5.2),程序会打印-5.2 | -5.2,所以字符串似乎不是空的。有没有办法从 C 中的字符串中拆分浮点数,然后存储剩余的字符串?

【问题讨论】:

  • 在使用任何结果变量之前,您需要检查sscanf 的返回值。在后一种情况下,您可能会发现它返回 1,这意味着它只匹配浮点数。
  • 即使是中等复杂的分词器也不会使用sscanfDFA 更适合您。查找 flex 和 bison。
  • @JeffHolt 我已经研究过 flex/bison,我可能最终会使用它。

标签: c string tokenize


【解决方案1】:

您可以使用strtof() function,它有一个参数(可选)返回一个指向输入字符串“其余部分”的指针(在提取float 之后):

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

int main(void)
{
    char str[] = "-5.2foo";
    char* rest;
    float f;
    f = strtof(str, &rest);
    printf("%f | %s\n", f, rest);
    // And, if there's nothing left, then nothing will be printed ...
    char str2[] = "-5.2";
    f = strtof(str2, &rest);
    printf("%f | %s\n", f, rest);
    return 0;
}

来自上面链接的 cppreference 页面(str_end 是第二个参数):

函数将 str_end 指向的指针设置为指向 解释的最后一个字符之后的字符。如果 str_end 为空 指针,它被忽略了。

如果输入字符串中没有'left',则返回值将指向该字符串的终止nul字符。

【讨论】:

  • float f = strtof(str, &amp;str);有什么问题吗?
  • @Andy 对第一个和第二个参数使用 same 指针是自找麻烦。如果您想稍后再使用str 怎么办。此外,在您的情况下,您将修改不应(不能)更改的内容 - 数组第一个元素的地址。
  • 事实上,对于显示的代码,使用f = strtof(str, &amp;str);会在clang-cl中给出这个:warning : incompatible pointer types passing 'char (*)[8]' to parameter of type 'char **' [-Wincompatible-pointer-types]
  • 但是如果我将字符串初始化为char *str = "-5.32";,这个错误就不会存在,对吧?
  • @AndySukowski-Bang strto函数的第二个参数被标记为restrict,理论上你不能重复使用它。
猜你喜欢
  • 1970-01-01
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
  • 2020-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-02
相关资源
最近更新 更多