E
Eric Lilja
Hello, I'm creating a small utility for an online game. It involves
parsing a text file of "tradesskill recipes" and inserting these
recipes in a gui tree widget (similar to gui file browsers if you know
what I mean).
Here's an example of a recipe as it appears in the text file:
* Cashew Pie (lvl 39, 5h 3 min, + max power)
- Candied Cashew (level 30)
-- Cashew
-- Refined Honey (level 30)
--- Raw Honey
--- Liquid
- Dough
- Refined Honey (level 30)
-- Raw Honey
-- Liquid
* denotes new recipe (a new root node in the tree)
-/--/--- denotes the depth of the child node.
One node per line.
The gui code is out of scope for the ng, but the parser is written in
standard C++, and I'm having some problems with it. The code:
#include <cassert>
#include <cctype>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <string>
using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;
using std::isspace;
using std::runtime_error;
using std::string;
enum depth_t { NO_DEPTH = 0, FIRST, SECOND, THIRD };
static depth_t get_depth(const string &);
int
main()
{
ifstream food_recipes_file("recipes_food.txt");
if(!food_recipes_file)
{
cerr << "Failed to open food recipe file." << endl;
return EXIT_FAILURE;
}
string line;
string recipe_root_node;
depth_t previous_depth = NO_DEPTH;
while(getline(food_recipes_file, line))
{
if(line[0] == '*')
{
assert(line[1] == ' ');
recipe_root_node = line.substr(2, line.length());
cout << "Inserting new recipe " << line << endl;
previous_depth = NO_DEPTH;
}
else if(isspace(line[0]))
; /* Simply skip lines beginning with a blank. */
else /* We're not dealing with a new recipe */
{
assert(line[0] == '-');
depth_t depth = get_depth(line);
cout << line << " at depth " << endl;
}
}
food_recipes_file.close();
return EXIT_SUCCESS;
}
/* get_depth() assumes the first char in line is a - */
static depth_t
get_depth(const string& line)
{
if(line[1] == ' ')
return FIRST;
/* If the second char is not a ' ', it must be a '-'. */
assert(line[1] == '-');
if(line[2] == ' ')
return SECOND;
/* If the third char is not a ' ', it must be a '-'. */
assert(line[2] == '-');
if(line[3] == ' ')
return THIRD;
throw runtime_error("Couldn't identify depth!");
}
This compiles without warning on my compiler (with warning level set to
max, all extension turned off), but the output is really messed up:
$ ./create_tree.exe
Inserting new recipe * Cashew Pie (lvl 39, 5h 3 min, + max power)
at depth Cashew (level 30)
at depth
at depth Honey (level 30)
at depth ney
at depth
at depth
at depth Honey (level 30)
at depth ey
at depth
Any obvious errors?
Thanks for any replies!
/ E
parsing a text file of "tradesskill recipes" and inserting these
recipes in a gui tree widget (similar to gui file browsers if you know
what I mean).
Here's an example of a recipe as it appears in the text file:
* Cashew Pie (lvl 39, 5h 3 min, + max power)
- Candied Cashew (level 30)
-- Cashew
-- Refined Honey (level 30)
--- Raw Honey
--- Liquid
- Dough
- Refined Honey (level 30)
-- Raw Honey
-- Liquid
* denotes new recipe (a new root node in the tree)
-/--/--- denotes the depth of the child node.
One node per line.
The gui code is out of scope for the ng, but the parser is written in
standard C++, and I'm having some problems with it. The code:
#include <cassert>
#include <cctype>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <string>
using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;
using std::isspace;
using std::runtime_error;
using std::string;
enum depth_t { NO_DEPTH = 0, FIRST, SECOND, THIRD };
static depth_t get_depth(const string &);
int
main()
{
ifstream food_recipes_file("recipes_food.txt");
if(!food_recipes_file)
{
cerr << "Failed to open food recipe file." << endl;
return EXIT_FAILURE;
}
string line;
string recipe_root_node;
depth_t previous_depth = NO_DEPTH;
while(getline(food_recipes_file, line))
{
if(line[0] == '*')
{
assert(line[1] == ' ');
recipe_root_node = line.substr(2, line.length());
cout << "Inserting new recipe " << line << endl;
previous_depth = NO_DEPTH;
}
else if(isspace(line[0]))
; /* Simply skip lines beginning with a blank. */
else /* We're not dealing with a new recipe */
{
assert(line[0] == '-');
depth_t depth = get_depth(line);
cout << line << " at depth " << endl;
}
}
food_recipes_file.close();
return EXIT_SUCCESS;
}
/* get_depth() assumes the first char in line is a - */
static depth_t
get_depth(const string& line)
{
if(line[1] == ' ')
return FIRST;
/* If the second char is not a ' ', it must be a '-'. */
assert(line[1] == '-');
if(line[2] == ' ')
return SECOND;
/* If the third char is not a ' ', it must be a '-'. */
assert(line[2] == '-');
if(line[3] == ' ')
return THIRD;
throw runtime_error("Couldn't identify depth!");
}
This compiles without warning on my compiler (with warning level set to
max, all extension turned off), but the output is really messed up:
$ ./create_tree.exe
Inserting new recipe * Cashew Pie (lvl 39, 5h 3 min, + max power)
at depth Cashew (level 30)
at depth
at depth Honey (level 30)
at depth ney
at depth
at depth
at depth Honey (level 30)
at depth ey
at depth
Any obvious errors?
Thanks for any replies!
/ E