简体   繁体   English

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

[英]How to extract floats from a string?

I am trying to extract float numbers from a string and after that they will be saved in an array.我正在尝试从字符串中提取浮点数,然后将它们保存在数组中。

Here's a code I found and even though I made the necessary changes it doesn't work:这是我找到的代码,即使我进行了必要的更改,它也不起作用:

#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;
}

Don't parse the string like that.不要像那样解析字符串。 Just read the values in your desired locale , for example most non-English European locales like de_DE.utf8 , ru_RU.utf8 , or it_IT.UTF-8 ... You can even set different locales for different streams, so for example below I'm using the default system locale for std::cin and a custom locale which uses : as the radix point in std::cout只需读取所需语言环境中的值,例如大多数非英语欧洲语言环境,如de_DE.utf8ru_RU.utf8it_IT.UTF-8 ...您甚至可以为不同的流设置不同的语言环境,例如下面我'm 使用std::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;
}

In C++ std::locale("") gives you the current system locale which is probably el_GR.UTF-8 in your case.在 C++ 中std::locale("")为您提供当前系统语言环境,在您的情况下可能是el_GR.UTF-8 You can also specify a specific locale to use such as std::locale("fr_FR.utf8") .您还可以指定要使用的特定语言环境,例如std::locale("fr_FR.utf8") Then use std::locale::global to set the obtained locale globally.然后使用std::locale::global设置获取的语言环境。 Each specific stream can further be imbue d to a different locale if necessary.如果需要,每个特定的流可以进一步被imbue到不同的语言环境。 You can also use setlocale for setting some locale preferences您还可以使用setlocale设置一些区域设置首选项

Sample output:样本输出:

$ 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

Notice the difference in the last output?注意到最后一个输出的不同了吗? That's because , is the thousand separator in the English locale那是因为,是英语语言环境中的千位分隔符

In the example above I'm setting the current locale via LC_ALL , but on Windows you can't change that easily from the console so just do that in your code.在上面的示例中,我通过LC_ALL设置当前语言环境,但在 Windows 上,您无法从控制台轻松更改,因此只需在代码中执行此操作即可。 And I'm printing the output directly but pushing it into an array is trivial我直接打印输出但是将它推入数组是微不足道的

Note that those online platforms don't have a non-US locale so I have to use the custom locale.请注意,这些在线平台没有非美国语言环境,因此我必须使用自定义语言环境。 On Linux you can check the available locales with locale -a在 Linux 上,您可以使用locale -a检查可用的语言环境


In case you really want to get the floating-point numbers as strings (why?) then just read normally.如果您真的想将浮点数作为字符串(为什么?)然后正常读取。 No need for such complex parsing.不需要如此复杂的解析。 std::cin and any kinds of istream will just stop at blank spaces as expected std::cin和任何类型的istream都会按预期停在空白处

#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;
}

Sample output:样本输出:

$ 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

Demo 演示

If you don't care about performance that much, you can use this simple algorithm :如果你不太关心性能,你可以使用这个简单的算法:

#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;
}

this algorithm goes through every char inside 'a' and checks:该算法遍历“a”中的每个字符并检查:

  • if digit or comma -> add it to buffer如果是数字或逗号 -> 将其添加到缓冲区
  • if space -> reading float ended (now looking for a new one), pushing buffer to array and clearing buffer so you can read new float如果空间->读取浮点数结束(现在正在寻找新的),将缓冲区推送到数组并清除缓冲区,以便您可以读取新的浮点数

if you want me to explain someting feel free to ask :)如果你想让我解释一下,请随时问:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM