快速解析配置的方法

时间:2009-04-06 19:27:57

标签: c++ stl

说你有

char *=  "name:454";

解析名称和数字的最佳方法是什么,因此

std:string id等于“name”;

double d等于454;

请STL,没有提升。

7 个答案:

答案 0 :(得分:4)

您希望使用':'作为令牌查看strtok函数。这是一个例子:

#include <stdio.h>
#include <string.h>

int main ()
{
    char str[] = "name:454";
    char* c = strtok(str, ":");

    while (c != NULL)
    {
        printf("%s\n", c);
        c = strtok(NULL, ":");
    }

    return 0;
}

答案 1 :(得分:2)

答案 2 :(得分:2)

不是你要求的stl解决方案;然而, 迟早你需要解析更复杂的表达式(暗示 - 比你预期的更早),此时你需要正则表达式 - 所以为什么不现在就开始。您的表达式由以下内容捕获:

^(\w+):(\d+)$

我不是狂热的狂热者,但他们的正则表达式库很不错。

答案 3 :(得分:1)

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

int main() {
  /* output storage */
  std::string id; 
  double d;
  /* convert input to a STL string */
  std::string s("name:454");
  size_t off = std::string::npos;
  /* smart replace: parsing is easier with a space */    
  if ((off = s.find(':')) != std::string::npos) { // error check: all or none 
    s = s.replace(off, 1, 1, ' ');
    std::istringstream iss(s);
    iss >> id >> d;
    std::cout << "id = " << id << " ; d = " << d << '\n';
  }
  return 0;
}

虽然,我只是编写自己的解析器或使用C扫描仪功能来提高速度。

答案 4 :(得分:0)

我会写自己的。基本思路是从流中一次读取一个字符。如果它不是冒号,则将其附加到id字符串。如果是,请跳过它,然后使用istream&gt;&gt;运算符加载整数,双浮点数或任何需要的值。然后你可能把结果放到std :: map。

答案 5 :(得分:0)

另一种可能性是使用已经编写的解析器来处理像INI这样的简单格式。

这是一个:http://code.jellycan.com/SimpleIni/

我查看了SimpleIni的代码,它不是很C ++和STL'ish,但你真的在乎吗?

答案 6 :(得分:0)

template < typename T >
T valueFromString( const std::string &src )
{
    std::stringstream s( src );
    T result = T();
    s >> result;
    return result;
}

std::string wordByNumber( const std::string &src, size_t n, const std::string &delims )
{
    std::string::size_type word_begin = 0;
    for ( size_t i = 0; i < n; ++i )
    {
        word_begin = src.find_first_of( delims, word_begin );
    }
    std::string::size_type word_end = src.find_first_of( delims, word_begin );

    word_begin = std::string::npos == word_begin || word_begin == src.length() ? 0 : word_begin + 1;
    word_end = std::string::npos == word_end ? src.length() : word_end;
    return src.substr( word_begin, word_end - word_begin);
}


char *a = "asdfsd:5.2";
std::cout << wordByNumber( a, 0, ":" ) << ", " << valueFromString< double > ( wordByNumber( a, 1, ":" ) );

PS:在之前的修订版中,我发布了wordByNumber - 它跳过了邻居分隔符(例如:: :),在当前版本中它们被视为空字。