Входные данные в формате C ++ должны соответствовать значению - PullRequest
2 голосов
/ 19 марта 2012

Я читаю файл с C ++; файл выглядит так:

tag1 2345
tag2 3425
tag3 3457

Я бы хотел что-то вроде

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

Где все взрывается, если то, что принимается, не соответствует аргументу must_be() и, когда сделано, var1=2345, var2=3425, var3=3457.

Есть ли стандартный способ сделать это? (Надеюсь, что «tag1» не обязательно должен быть строкой, но это не является обязательным требованием.) fscanf из C сделал это довольно просто.

Спасибо!

Для пояснения, каждый >> читает в одном наборе символов, разделенных пробелами, из input. Я хочу сопоставить некоторые входящие блоки символов (tagX) со строками или данными, которые я указал.

Ответы [ 2 ]

0 голосов
/ 19 марта 2012

Разве вы не можете прочитать это построчно и сопоставить теги для каждой строки?Если тег не соответствует ожидаемому, просто пропустите строку и перейдите к следующей.

Примерно так:

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 голосов
/ 19 марта 2012

Вам нужно реализовать 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;
}

Обратите внимание, что при неправильном значении тега будет сгенерировано исключение (что означает, что тег будет соответствовать).

...