2012-03-19 36 views
2

我正在用C++读取文件;该文件看起来像:C++格式化的输入必须匹配值

tag1 2345 
tag2 3425 
tag3 3457 

我想在哪里,如果什么东西被采取不匹配的must_be()的说法,并完成后,var1=2345, var2=3425, var3=3457一切炸毁有类似

input>>must_be("tag1")>>var1>>must_be("tag2")>>var2>>must_be("tag3")>>var3; 

有没有这样做的标准方式? (希望“tag1”不一定是字符串,但这不是必需的。)来自C的fscanf使它非常容易。

谢谢!

为了澄清,每个>>都从input中读取一个以空格分隔的字符集。我希望将一些即将到来的字符块(tagX)与我指定的字符串或数据进行匹配。

回答

0

您需要为您的班级实施operator>>。事情是这样的:

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

struct A 
{ 
    A(const int tag_):tag(tag_),v(0){} 

    int tag; 
    int v; 
}; 

#define ASSERT_CHECK(chk, err) \ 
     if (!(chk)) \ 
      throw std::string(err); 

std::istream& operator>>(std::istream & is, A &a) 
{ 
    std::string tag; 
    is >> tag; 
    ASSERT_CHECK(tag.size() == 4, "tag size"); 
    std::stringstream ss(std::string(tag.begin()+3,tag.end())); 
    int tagVal; 
    ss >> tagVal; 
    std::cout<<"tag="<<tagVal<<" a.tag="<<a.tag<<std::endl; 
    ASSERT_CHECK(a.tag == tagVal,"tag value"); 

    is >> a.v; 
    return is; 
} 

int main() { 
    A a1(1); 
    A a2(2); 
    A a3(4); 

    try{ 
     std::fstream f("in.txt"); 
     f >> a1 >> a2 >> a3; 
    } 
    catch(const std::string &e) 
    { 
     std::cout<<e<<std::endl; 
    } 

    std::cout<<"a1.v="<<a1.v<<std::endl; 
    std::cout<<"a2.v="<<a2.v<<std::endl; 
    std::cout<<"a3.v="<<a3.v<<std::endl; 
} 

大家注意到,对于错误的标签值,将引发异常(指标签太多比赛)。

+0

但你知道一个标准的(库/升压)这样的方式? – Richard 2012-03-19 14:54:49

+0

@Richard这是一个标准的做法。只要为你的班级实施'operator >>',你应该很好。 boost并不为运营商>>提供自定义类 – 2012-03-19 16:20:35

0

难道你不能一行一行阅读它,并为每一行匹配标签吗?如果标签与您所期望的不符,您只需跳过该行并转到下一行。

事情是这样的:

const char *tags[] = { 
    "tag1", 
    "tag2", 
    "tag3", 
}; 
int current_tag = 0; // tag1 
const int tag_count = 3; // number of entries in the tags array 

std::map<std::string, int> values; 

std::string line; 
while (current_tag < tag_count && std::getline(input, line)) 
{ 
    std::istringstream is(line); 

    std::string tag; 
    int value; 
    is >> tag >> value; 

    if (tag == tags[current_tag]) 
     values[tag] = value; 
    // else skip line (print error message perhaps?) 

    current_tag++; 
} 
+0

但是您是否知道这样做的标准(库/增强)方式? – Richard 2012-03-19 14:55:09

+0

@Richard也许[Boost.spirit](http://www.boost.org/doc/libs/1_49_0/libs/spirit/doc/html/index.html)? – 2012-03-19 15:19:01