如何从字符串中提取浮点数?

How to extract floats from a string?

提问人:Αλέξανδρος Ζωγράφος 提问时间:6/6/2022 最后编辑:phuclvΑλέξανδρος Ζωγράφος 更新时间:6/10/2022 访问量:922

问:

我正在尝试从字符串中提取浮点数,然后它们将被保存在数组中。

这是我找到的代码,即使我进行了必要的更改,它也不起作用:

#include <iostream>
#include <string>
using namespace std;

string a="2,134 43,54 22,334";
string b[30];

int found,i=0;
while(a!="\0"){
found=a,find("\t");
for(int f=0;f<found;f++){
b[i]+=a[f];
}
a.erase(0,found+1);
i++;
}
for(int d=0;d<i;d++){
cout<<b[d]<<endl;
}
return 0;
}
C++ 数组字符串 输入 浮点

评论

1赞 UnholySheep 6/6/2022
“不起作用”是一个可怕的问题描述。你应该尽可能具体
0赞 UnholySheep 6/6/2022
此外,您应该从制作一个适当的最小可重复示例开始。发布的代码无法编译
0赞 PhilMasteG 6/6/2022
欢迎使用 StackOverflow。通过快速浏览您的代码,我注意到您在搜索拆分时字符串中的空格字符。a"\t"
2赞 phuclv 6/6/2022
正确缩进代码。这是编程时必须做的最基本的事情之一。另请参阅为什么“使用命名空间 std;”被认为是不好的做法?

答:

0赞 KokosNaPalmie 6/6/2022 #1

如果你不太关心性能,你可以使用这个简单的算法:

#include <iostream>
#include <vector>


int main()
{
    std::string a = "2,134 43,54 22,334";

    std::vector<std::string> floats; // I used vector instead of array - easier and safer

    std::string buffer;
    for (auto& itr : a)
    {
        if (itr == ' ') // space -- float ended
        {
            floats.push_back(buffer);
            buffer.erase();
        }
        else
        {
            buffer += itr;
        }
    }

    if (!buffer.empty()) // if something left in the buffer -> push it
        floats.push_back(buffer);

    // printing 'floats' array
    for (auto& itr : floats)
        std::cout << itr << '\n';

   return 0;
}

该算法遍历“a”中的每个字符并检查:

  • 如果数字或逗号 -> 将其添加到缓冲区
  • 如果空格 -> 读取浮点数结束(现在正在寻找新的浮点数),将缓冲区推送到数组并清除缓冲区,以便您可以读取新的浮点数

如果你想让我解释一些事情,请随时问:)

1赞 phuclv 6/6/2022 #2

不要这样解析字符串。只需读取所需区域设置中的值,例如大多数非英语欧洲区域设置,如 、 或 ...您甚至可以为不同的流设置不同的语言环境,例如下面我使用默认的系统语言环境和用作基数点的自定义语言环境de_DE.utf8ru_RU.utf8it_IT.UTF-8std::cin:std::cout

#include <iostream>
#include <sstream>
#include <locale>
#include <clocale>
#include <stdlib.h>

template <class charT, charT sep>
class punct_facet: public std::numpunct<charT> {
protected:
    charT do_decimal_point() const { return sep; }
};

int main(int argc, char** argv) {
    // Use default locale for most std streams
    std::locale::global(std::locale(""));
    // Use C locale with custom radix point for stdout
    std::cout.imbue(std::locale(std::locale("C"), new punct_facet<char, ':'>));

    std::stringstream str(argv[1]);
    double d;
    while (str >> d)
    {
        std::cout << d << '\n';
    }
    return 0;
}

在 C++ 中,std::locale(“”) 为您提供当前的系统语言环境,这可能是您的情况。您还可以指定要使用的特定区域设置,例如 。然后使用 std::locale::global 全局设置获取到的区域设置。如有必要,每个特定流都可以进一步注入到不同的语言环境中。您还可以使用 setlocale 来设置某些区域设置首选项el_GR.UTF-8std::locale("fr_FR.utf8")

示例输出:

$ g++ read_locale.cpp -o read_locale
$ LC_ALL=el_GR.UTF-8 ./read_locale "2,134 43,54 22,334"
2:134
43:54
22:334
$ LC_ALL=en_US.utf8 ./read_locale "2.134 43.54 22,334"
2:134
43:54
22334

注意到最后一个输出的差异了吗?这是因为英语语言环境中的千位分隔符,

在上面的示例中,我通过LC_ALL设置当前区域设置,但在 Windows 上,您无法从控制台轻松更改,因此只需在代码中执行此操作即可。我直接打印输出,但将其推送到数组中是微不足道的

请注意,这些在线平台没有非美国语言环境,因此我必须使用自定义语言环境。在 Linux 上,您可以使用以下命令检查可用的语言环境locale -a


如果你真的想把浮点数作为字符串(为什么?),那么就正常阅读吧。不需要如此复杂的解析。 任何类型的 istream 都会像预期的那样停在空白处std::cin

#include <iostream>
#include <sstream>
#include <string>

int main(int argc, char** argv) {
    std::stringstream str(argv[1]);
    std::string s;
    while (str >> s)
    {
        std::cout << s << '\n';
    }
    return 0;
}

示例输出:

$ g++ read_numbers_as_string.cpp -o read_numbers_as_string
$ ./read_numbers_as_string "2,134 43,54 22,334"
2,134
43,54
22,334

演示