2

私はC++が初めてで、ファイルストリームの読み取り全体を理解するのに少し問題があります..どんな助けもいただければ幸いです...ここで私は問題を抱えています

私はこのような構造の配列を持っています; (いいえ、明らかにこれらのものを格納するために文字列を使用することは許可されていません。また、ベクトルや、私がカバーしていないその他のより高度なものを使用することも許可されていません)...

struct Staff
{
    char title[TITLESIZE];
    char firstName[NAMESIZE];
    char familyName[NAMESIZE];
    char position[POSSIZE];
    char room[TITLESIZE];
    char email[POSSIZE];
};

次に、これらの構造の配列があります。

Staff record[MAXNOSTAFF];

データは、タブで区切られたテキスト ファイルに含まれています。ただし、一部のフィールドには空白が含まれる場合があります。以下のようなデータ:

Dr Sherine ANTOUN Lecturer 4327 3.204 sherine_antoun@gmail.com

これが私のコードに書いたものです...

//function prototypes
bool getRecord (ifstream& infile, Staff dataAr[], bool& fileFound);

int main()
{

    Staff record[MAXNOSTAFF];
    bool fileFound;
    ifstream infile;

    getRecord(infile, record, fileFound); //function call
    if (fileFound==true) 
    {
        cerr <<"Exiting Program"<<endl;
        exit(1);
    }

    return 0;
}

//function definitions
bool getRecord (ifstream& infile, Staff dataAr[], bool& fileFound)
{
    infile.open("phonebook.txt");

    if (infile)
    {
        fileFound = true;
        cout << "File " <<PHONEBOOK<< " opened successfully.\n\n";
    }
    else if (!infile)
    {
        fileFound =  false;
        cerr << "Error! File could not be opened. \n";
    }

    while (infile.good())
    {        

        for (int lineIndex=0; lineIndex<MAXNOSTAFF; lineIndex++)
            for (int titleIndex=0; titleIndex<TITLESIZE; titleIndex++)
            {
                cin.getline(dataAr[lineIndex].title[titleIndex], MAXNOSTAFF, '/t');
            }

    }
    //check it works properly
    for (int k=0;k<10; k++)
    {
        for (int m=0; m<11; m++)
        {
            cout << k <<". Title is : "<<dataAr[k].title[m]<<endl;
        }
    }    
    infile.close();
    return fileFound;
}

どんな助けでも大歓迎です..ありがとう

4

2 に答える 2

2

このような入力データを解析するブースト スピリットのアプローチをお見せしましょう。

次のような構造体で開始する場合

struct Staff
{
    std::string title;
    std::string firstName;
    std::string familyName;
    std::string position;
    std::string room;
    std::string email;
};

次のような Spirit 文法を使用できます。

    column = lexeme [ *~char_("\t\r\n") ];
    start  = column >> '\t'  >> column >> '\t' >> column >> '\t' >> column >> '\t' >> column >> '\t' >> column;

そして、すべての行を次のようなベクトルに解析します。

    It f(std::cin), l;
    std::vector<Staff> staff_members;
    bool ok = qi::parse(f, l, grammar % qi::eol, staff_members);

    if (ok)
    {
        for(auto const& member : staff_members)
        {
            std::cout << boost::fusion::as_vector(member) << "\n";
        }
    } else
    {
        std::cout << "Parsing failed\n";
    }

    if (f != l)
        std::cout << "Remaining input '" << std::string(f, l) << "'\n";

完全なテスト プログラムLive on Coliru、サンプル実行は次のとおりです。

clang++ -std=c++11 -Os -Wall -pedantic main.cpp && ./a.out <<INPUT
Dr  Sherine ANTOUN  Lecturer    4327    3.204   sherine_antoun@gmail.com
Mr  Jason SCRYPT    Enthusiast  3472    9.204   jason_scrypt@yahoo.com
INPUT

出力:

(Dr Sherine ANTOUN Lecturer 4327 3.204 sherine_antoun@gmail.com)
(Mr Jason SCRYPT Enthusiast 3472 9.204 jason_scrypt@yahoo.com)
Remaining input '
'

完全なリスト

#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/tuple/tuple_io.hpp>

namespace qi = boost::spirit::qi;

struct Staff
{
    std::string title;
    std::string firstName;
    std::string familyName;
    std::string position;
    std::string room;
    std::string email;
};

BOOST_FUSION_ADAPT_STRUCT(Staff, 
    (std::string, title)
    (std::string, firstName)
    (std::string, familyName)
    (std::string, position)
    (std::string, room)
    (std::string, email))

template <typename It, typename Skipper = qi::unused_type>
    struct grammar : qi::grammar<It, Staff(), Skipper>
{
    grammar() : grammar::base_type(start)
    {
        using namespace qi;
        column = lexeme [ *~char_("\t\r\n") ];
        start  = column >> '\t'  >> column >> '\t' >> column >> '\t' >> column >> '\t' >> column >> '\t' >> column;
    }
    private:
    qi::rule<It, std::string(), Skipper> column;
    qi::rule<It, Staff(), Skipper> start;
};

int main()
{
    std::cin.unsetf(std::ios::skipws);

    typedef boost::spirit::istream_iterator It;
    grammar<It> grammar;

    It f(std::cin), l;
    std::vector<Staff> staff_members;
    bool ok = qi::parse(f, l, grammar % qi::eol, staff_members);

    if (ok)
    {
        for(auto const& member : staff_members)
        {
            std::cout << boost::fusion::as_vector(member) << "\n";
        }
    } else
    {
        std::cout << "Parsing failed\n";
    }

    if (f != l)
        std::cout << "Remaining input '" << std::string(f, l) << "'\n";
}
于 2014-03-18T15:19:43.800 に答える