解析文本文件,直到找到浮点数?

时间:2014-09-22 02:14:23

标签: c++ parsing

我正在尝试解析文本文件中的行。每行代表一个股票代码并具有相同的格式,具有随机数量的字符串(对于公司名称+符号),后跟均匀数量的浮点数(每行的数量相同)。

如何检查最后一个读取的字符串是否为浮点数,以便知道何时到达字符串的末尾并开始解析浮点数?

示例文字行:

A.M. CASTLE & COMPANY CAS 15.71 0.55  3.63 31.57 17.97 8.99 7.79
AAR CORP AIR 17.79 0.19  1.08 30.62 18.45 10.51 38.26 
ABBOTT LABORATORIES ABT 45.14 0.01  0.02 -3.24 50.00 40.25 20.33 

示例代码:

void parse(string filename){
    ifstream myfile;        
    string line;
    string current_word;

    myfile.open(filename);
    if (myfile.is_open()){
        while (getline(myfile, line))
        {
            stringstream current_line(line);
            while (current_line >> current_word){
                // How can I test when I have reached a float here?
            }
        }
    }
}

4 个答案:

答案 0 :(得分:2)

您可以测试数字的流读数以查看它是否成功,如果它是这样的话,则使用该值:

int main()
{
    std::string line = "A.M. CASTLE & COMPANY CAS 15.71 0.55 3.63 31.57 17.97 8.99 7.79";

    std::istringstream iss(line); // convert the line into a stream

    std::string item;
    while(iss >> item) // read the stream items (space separated) one by one
    {
        float f;
        if(std::istringstream(item) >> f) // does this item read as a float?
        {
            // use f here if it does
            std::cout << f << " ";
        }
    }
}

答案 1 :(得分:1)

如果你保证浮动之前的所有字符串都不包含数字,那么你可以简单地比较每个字符,直到找到一个数字,并找到浮点数的第一个字符。

如果没有这种保证,我可能会解析单词。将每个字符添加到字符串直到找到空格是一件小事。如果该字符串仅包含数字和一个句点,那么您就找到了浮点数。否则,跳过下一个非空格字符,再次执行相同的操作。

答案 2 :(得分:0)

您可以使用sscanf(),它将在一行中执行请求的操作。

bool parseNameAndFloats(char const *input, char *name, unsigned int namesize, float *floatArray, unsigned int floatsize)
{
    // Assuming the sample string is representative, there's 7 floats in it.
    if (floatsize < 7)
    {
        return false;
    }
    char *temp = strdup(input);
    if (temp == NULL)
    {
        // deal with allocation failure in strdup;
        return false;
    }
    int count = sscanf(input, "%[^0-9.]s %f %f %f %f %f %f %f", temp, floatArray, floatArray + 1, floatArray + 2, floatArray + 3, floatArray + 4,floatArray + 5, floatArray + 6);
    if (namesize > 0)
    {
        strncpy(name, temp, namesize);
        name[namesize - 1] = 0;
    }
    free(temp);
    return count == 8;
}

有些人会批评sscanf(),如果使用不当,可能会导致一些重大问题。其中之一就是我使用strdup()制作原始输入字符串的副本。这保证会给我一个足够大的缓冲区来保存%[^0-9.]s转换的结果。然后我使用strncpy()提取不超过提供的缓冲区,并确保NUL终止。

答案 3 :(得分:0)

使用C ++ 11中提供的正则表达式。

仔细检查浮点数的模式。例如。我的表达不允许有前导符号。

#include <iostream>
#include <ostream>
#include <regex>
#include <sstream>
#include <string>

int main()
{
    std::istringstream input("A.M. CASTLE & COMPANY CAS 15.71 0.55 3.63 31.57 17.97 8.99 7.79");

    // Pattern for recognizing floating-point numbers
    std::regex pattern(R"(\d+\.(\d*)?((e|E)(\+|\-)?\d+)?)");

    for (std::string line; std::getline(input, line); )
    {
        // We have a successful read of one line
        // Now extract the floating-point numbers on that line

        auto first = std::sregex_iterator(line.cbegin(), line.cend(), pattern);
        auto last = std::sregex_iterator();
        for (; first != last; ++first)
        {
            double d = std::stof(first->str());
            std::cout << d << std::endl;
        }
    }

    return 0;
}