2012-03-19 40 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