Jump to content
  • Advertisement
Sign in to follow this  
NewbJ

String class

This topic is 4898 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

A problem has just come up with the string class in a math program I'm writing. The program solves algebraic equations. For example, the user might input 23x+56=86 and it solves for x. I hope to eventually get it much more complex, incorporating powers and logs and such, but for now I'm keeping it simple to get the basis. Anyway, there is a part of it in which the program reads a digit from a longer string, puts in in another string, checks to see if the next character is a digit, if so puts it in the other string, etc. so that the entire coefficient (for example, 23) might be in that other string. Here is the portion of code that does that: (tempNum and _equ_in are both std::strings)
                int counter = 1;      
                while (flag != true)
                {
                    tempNum[counter-1] = _equ_in[markerPos+(counter-1)];

                    //if the next character is NOT a number 0-9, break the loop
                    if ( ((int)_equ_in[markerPos+counter] < 48) ||
                         ((int)_equ_in[markerPos+counter] > 57) )
                    {
                        flag = true;
                    }
                    else
                    {
                        counter++;
                    }
                } //end while  




I then send tempNum off to another function to get turned into an int. This is no problem. My problem is that when I display each individual element of temNum, it works fine, but when I try to display the entire number, as in "cout << temNum;", nothing is displayed. Am I using the string class incorrectly?

Share this post


Link to post
Share on other sites
Advertisement
A much cleaner way of extracting things from std::strings is to use the std::istringstream class.

for example:



std::string someNumbers("10+11+12");
std::istringstream cStream(someNumbers);

int cNumber;
cStream >> cNumber;




I took that from another program so it is probably not immediately useful, but its really just a hint to get you started.

Share this post


Link to post
Share on other sites
May I highly recommend boost's spirit library. It gets some getting used to, but the online docs are excellent. What you basically do is define a grammar and either semantic actions are performed when a match is found, or a Parse Tree can be generated, which you can then iterate over.

There's also some example programs here which show how to use it, including PlainCalc, which seems to be what you're trying to do - perhaps you could look at the source and get some hints.

Like I said, it may seem complicated at first, but once you get the hang of it it's quite intuitive to use. Plus if you get any problems, I'm sure someone here will be able to help you. points towards Mauling Monkey

Share this post


Link to post
Share on other sites
Thanks to you both. I will look into both istringstream stuff and boost's spirit library. Though I will probably use these to solve my problem, does anyone know what specifically is wrong with my current code? I would only like to know so that I don't make the same mistake again.

Share this post


Link to post
Share on other sites
Another possibility for this would be to go for a generic lexer/parser class combination (eventually made with lex/yacc or flex/bison). They will generate a parse tree for you of the expression you want to calculate like for expression (4-6)+6 it will generate this operator tree:


+
/ \
- 6
/
4 6


When you have this tree you can easily walk trough the nodes and their children like the following:

double calculate (treenode* node)
{
switch (node->op)
{
case opSub:
return node->left->val - node->right->val;
case opAdd:
return node->left->val + node->right->val;
default:
printf ("Invalid operator!\n");
}
return 0;
}



It looks a bit like that you are creating a compiler, but you aren't. This code is very extensible and can support all kinds of operators etc.

Good luck!

EDIT: mm.. the tree isnt very nice as plain html

Share this post


Link to post
Share on other sites
Quote:
Original post by NewbJ
I then send tempNum off to another function to get turned into an int. This is no problem. My problem is that when I display each individual element of temNum, it works fine, but when I try to display the entire number, as in "cout << temNum;", nothing is displayed. Am I using the string class incorrectly?


I'm not checking to make certain I'm correct, but I'm pretty sure you're not. (I've just never used strings in this manner) You need to reserve space for characters you are putting into tempNum, I think you're corrupting memory.

Instread of :
tempNum[counter-1] = _equ_in[markerPos+(counter-1)];

try :
tempNum.push_back(_equ_in[markerPos+(counter-1)]);


You don't show the conversion code, but you need to use invoke the member function c_str() to get a null-terminated string from a std::string to use C functions on them (neither &*string.begin() nor &string[0] is correct for this case).

You should read "Effective STL" by Scott Meyers and/or pick-up Josuttis's book on the standard library.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!