1

So I have a simple carriage-return separated file that reads:

room(800,400)
place(desk, 5, 6)
place(chair, 8, 5)
place(bed, 6, 6)
place(closet, 1, 4)

I am trying to store the occurrence of each keywords (desk, chair, bed and closet) and the related x, y and store somewhere (not important!) and extract the room dimensions and again store somewhere. My code looks like:

#include <iostream>
#include <fstream>
#include <string>
using namepace std;

void Keyword(ifstream & stream, string token) {
    string line;
    while (getline(stream, line)) {
        if (line.find(token) != string::npos) {
            cout << line << endl;

            if(token == "room") {
                //store the numbers and string to somewhere
            }

            if (token == "table") {
                //store the numbers and string to somewhere
            }
        }
    }
    cout << token << " Not Found!" << endl;
}

int main()
{

    // Shape Grammar Parser  
    ifstream infile("shape.dat");

    Keyword(infile, "room");    
    return 0;
}

What I am trying to do is, when the parser sees place(chair, 8, 5) it stores in a data structure chair, 8, 5, or when it sees room it extracts room, 800, 400.

However the above implementation is broken as with this implementation I can only extract chair and not the related numbers. How can that be done? I am totally inexperienced with regular expressions so I did not try it.

Jishan
  • 1,654
  • 4
  • 28
  • 62

3 Answers3

2

The logic here is upside down. Instead of passing a token name to Keyword (which needs a better name; parse_file might be more descriptive), call Keyword with just an istream&. Let Keyword do the work of figuring out which tokens are present:

while (get_line(stream, line)) {
    std::string::size_type pos = line.find('(');
    if (pos == std::string::npos)
        throw file_read_failure(); // user-defined exception type
    std::string token = line.substr(0, pos);
    if (token == "room")
        parse_room(line.substr(pos));
    else if (token == "table")
        parse_table(line.substr(pos));
    // et cetera
Pete Becker
  • 74,985
  • 8
  • 76
  • 165
  • Just so that I understand correctly, after I use substring to separate the number portion should I just look for comma and extract the 2 numerals? Any fast way to do this? – Jishan Feb 08 '17 at 16:40
1

An easy, simple and nice way, std::regex_iterator

std::basic_regex< char > regex ( "\\d+" );
std::string string = "place(closet, 1, 4)";

std::regex_iterator< std::string::iterator > first ( string.begin(), string.end(), regex );
std::regex_iterator< std::string::iterator > last;

while( first != last ){ std::cout << first->str() << ' '; ++first; }  

output

1 4


Instead of string that I wrote you can pass your string. that's it.

Shakiba Moshiri
  • 21,040
  • 2
  • 34
  • 44
1

try this code

void Keyword(ifstream & stream, string token) {
    string line;

    int dimension1;
    int dimension2;
    string item_in_room;

    while (getline(stream, line,'(')) {

        if ( !line.compare("room") )
        {
            getline(stream, line,',');
            dimension1 = atoi( line.c_str() );

            getline(stream, line,')');
            dimension2 = atoi( line.c_str() );

            cout << "It's a room, dimensions: " << dimension1 << " , " << dimension2 << endl;
        }

        if ( !line.compare("place") )
        {
            getline(stream, item_in_room,',');

            getline(stream, line,',');
            dimension1 = atoi( line.c_str() );

            getline(stream, line,')');
            dimension2 = atoi( line.c_str() );

            cout << "It's a " << item_in_room << " dimensions: " << dimension1 << " , " << dimension2 << endl;
        }

        //read the rest of the line, just to get to a new new
        getline(stream, line);
    }
    cout << token << " Not Found!" << endl;
}

It works and here is the output:

It's a room, dimensions: 800 , 400

It's a desk dimensions: 5 , 6

It's a chair dimensions: 8 , 5

It's a bed dimensions: 6 , 6

It's a closet dimensions: 1 , 4

room Not Found!

Press any key to continue . . .