0

There is also a C++ string class that is not the same as a C style string and the C string functions may not work with it.

You can retrieve a C style string from the C++ string class using the .c_str() function, but it is a const char * and modifying it that way probably isn't recommended.

With the C++ string class you don't really need the C string functions.

#include <iostream>
#include <string>
#include <algorithm>
#include <sstream>
using namespace std;

int main()
{
	string cppString = "Hello World.";
	cppString = "No error, no confusing C functions.";
	getline(cin,cppString);//No buffer overflow from too much input.

	//Use much like an array.
	for( std::string::size_type i = 0; i < cppString.size(); i++ )
		 cppString[i] = 'x';

	cppString += " -- Simple string concatenation too.";

	//Usable with the C++ STL algorithms.
	random_shuffle(cppString.begin(), cppString.end());

	cout << "Can still get a C string if you REALLY want to also." 
		<< endl << cppString.c_str() << endl;

	//Easily convert from string to int/floating point type.
	int someInt = 0;
	cin >> cppString;
	if((stringstream(cppString) >> someInt).fail())
		cout << "Invalid number, woops!";
	else
		cout << someInt << endl << "Just your lucky number." << endl;
}

Sorry, if you want to convert your string to an integer or other type you can use a stringstream. They're pretty simple once you get used to the idea.

Edited by pseudorandom21: n/a

0

ok, i built that code into my equation solver and it works. the only problem is that i cant enter my whole equation in a single line. i have to type my first number, press enter, type my operator, press enter, type my variable, press enter, type =, press enter, and then type in my last number and press enter. it gets kind of annoying after a while.

0

To get multiple things on one line, try:

cin >> n1string >> operator1string >> n2string >> operator2string >> n3string;

or maybe

getline(cin, cppString);
stringstream theStream(cppString);
if((theStream >> someInt).fail())
    cout << "Invalid number, woops!" << endl;
else if((theStream >> operator1).fail())
    cout << "Couldn't get first operator" << endl;
else if((theStream >> n2).fail())
    cout << "Invalid 2nd number" << endl;
...
0

those two code snippets that you posted, raptr_dflo, didnt work. Heres the equation solver code:

#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<sstream>
using namespace std;
int main (char argc)
{
    
    for(;;)
    {
           
    cout << "Variable equation solver version 1.2" << endl;
    cout << "Limitations: no ( and ),and no ^." << endl;
    cout << "Only variable allowed: x" << endl;
    cout << "press enter after you type in each number and operator." << endl;
    
    char operators, operators2;
    
    string n1, n2, n3;
    float ans;

    cin >> n1;
    
    cin >> operators;
    
    cin >> n2;
    
    cin >> operators2;
    
    cin >> n3;


    
    for(;;)
    {
           
    
    if(n1 == "x")
    { 
          int n2_value = 0;
          int n3_value = 0;
          
          stringstream(n2) >> n2_value;
          stringstream(n3) >> n3_value;



          if(operators == '+')
          {
                       ans = n3_value - n2_value;
          }
          
          if(operators == '-')
          {
                       ans = n3_value + n2_value;
          }
          
          if(operators == '/')
          {
                       ans = n3_value * n2_value;
          }
          
          if(operators == '*')
          {
                       ans = n3_value / n2_value;
          }
          
          cout << "the variable equals "<<ans<< endl;
          break;
          
    }
    
    if(n2 == "x")
    {
          float n1_value = 0;
          float n3_value = 0;
          
          stringstream(n1) >> n1_value;
          stringstream(n3) >> n3_value;
          
          
          if(operators == '+')
          {
                       ans = n3_value - n1_value;
          }
          
          if(operators == '-')
          {
                       ans = n3_value + n1_value;
          }
          
          if(operators == '/')
          {
                       ans = n3_value / n1_value;
          }
          
          if(operators == '*')
          {
                       ans = n3_value / n1_value;
          }
          cout << "the variable equals "<<ans<< endl;
          break;
         
          }
          
          if(n3 == "x")
          {
                float n1_value = 0;
                float n2_value = 0;
          
                stringstream(n1) >> n1_value;
                stringstream(n2) >> n2_value;
          

                
                if(operators == '+')
          {
                       ans = n1_value + n2_value;
          }
          
          if(operators == '-')
          {
                       ans = n1_value - n2_value;
          }
          
          if(operators == '/')
          {
                       ans = n1_value / n2_value;
          }
          
          if(operators == '*')
          {
                       ans = n1_value * n2_value;
          }
          cout << "the variable equals "<<ans<< endl;
          break;

          }
          
          }
          system("pause");
          system("cls");
    }
}

Edited by thecoolman5: forgot to revert code

0

Describe "didn't work". I just wrote, compiled, and tested the following, and it worked just fine:

#include <iostream>
#include <string>
using namespace std;

int main (void)
{
        string n1, n2, n3;
        char operators, operators2;

        cout << "Enter an equation: n1 op n2 op n3" << endl
             << "n values can be integers or variables" << endl;

        cin >> n1 >> operators >> n2 >> operators2 >> n3;

        cout << "You typed: " << n1 << " " << operators << " " << n2 << " "
             << operators2 << " " << n3 << endl;
}
0

ok. i dont know why but after i enter my equation, C++ wants me to enter 4 more strings. so i type x+3=2 and press enter, but it doesnt output the equation. Then i enter 4 more variables and then it outputs x+3=2 d d d d. there has got to be some type of invisible loop.

0

i just recently changed the line from cin >> n1 >> operators >> n2 >> operators2 >> n3; to cin >> n1; that time it outputed the equation but following it was "v" and a white square.

0

Hmmm.... Sorry, I have no clue why the same code would work as expected for me -- at least acting like it's breaking the input on whitespace and assigning the variables in order -- but not for you.

For what it's worth, I just tried inputting and outputting only n1 (of type string ), and typing in the space-separated formula x + 3 = 5 , and the output gave me just "x". So it would appear that istream does break on whitespace....

0

i am sorry, but you told me to put spaces, raptr_dflo, in between the items. I thought you were talking about cin >>(space)n1(space). so i put in x + 3 = 2 and the program worked fine. is there any way to not have to put spaces?

0

oh and, i am also making it so you can put x + x = 56. and i have to create random numbers for the two x's. when i started, i had it output what the random numbers were and for some reason, C++ thinks of the exact same number about 20 times. how would you stop that?

0

thecoolman5,
I got started on another parsing loop for not-requiring-spaces-between-tokens, but got dragged away from it, will try to get back to you today. As far as the random numbers, feel free to post just the relevant lines of code near where you assign and print the values, and I'll see what's going on.

0

ok, heres the code

#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<sstream>
#include<ctime>
#include<cmath>
using namespace std;
int main (char argc)
{
    
    for(;;)
    {
           
    cout << "Variable equation solver version 2" << endl;
    cout << "Limitations: no ( and ),and no ^." << endl;
    cout << "Only variable allowed: x" << endl;
    cout << "One space between each item." << endl;
    
    char operators, operators2, operators3;
    
    string n1, n2, n3, n4;
    long double ans, ans2;
    

    cin >> n1;
    cin >> operators;
    cin >> n2;
    cin >> operators2;
    cin >> n3;
for(;;)
    {
       

if(n1 == "x")
          if(n2 == "x")
          {
                float n3_value = 0;
                stringstream(n3) >> n3_value;
                
                cout << "Variable range max: " << endl;
                int rr2;
                cin >> rr2;
                
                int rr1;
                rr1 = rr2 * -1;
                
                for(;;)
                {
                
                srand((unsigned)time(0)); 
                int r1 = rand();
                int lowest=rr1, highest=rr2;    
                int range=(highest-lowest)+1;              
                r1 = lowest+int(range*rand()/(RAND_MAX + 1.0)); 
                
                srand((unsigned)time(0)); 
                int r2 = rand();
                lowest=rr1, highest=rr2;    
                range=(highest-lowest)+1;              
                r2 = lowest+int(range*rand()/(RAND_MAX + 1.0)); 
                
                if(operators == '+')
          {
                       ans = r1 + r2;
          }
          
          if(operators == '-')
          {
                       ans = r1 - r2;
          }
          
          if(operators == '/')
          {
                       ans = r1 / r2;
          }
          
          if(operators == '*')
          {
                       ans = r1 * r2;
          }
          
          if(ans == n3_value)
          {
                 cout << "the variables equal "<<r1<< ", and "<<r2<< endl;
                 break;
          }
          
          if(ans - n3_value)
          {
                 cout <<r1<<" " <<r2<< endl;
          }
          }

just enter x + x = 5 and it should post every number that it thinks of.

Edited by thecoolman5: n/a

0

Real quick, you have an infinite loop starting at line 30 above, and another one starting after you check that n1 and n2 are both x and you get n3 and the random number range, starting at line 47.

Also, you don't need to reseed the random number generator for each number, just call srand() once, before you ever start looping. Since it looks like lowest, highest and range don't change, you can also declare and assign those outside your loop, and there's no benefit to assigning r1=rand() and then re-assigning it three lines lower (same for r2).

Does any of that help?

0

that didnt really help. i replaced

srand((unsigned)time(0));

with

srand(r1);

on the random number generator and all it did was make C++ think of only two numbers. the random number generator has to create random numbers every time that code comes up in the compiler. I want it to stop thinking of the same number 20 times in a row. im assuming that you took my previous code and ran it, and you saw the program thinking of the same number 20 times in a row. after 20 times, it switches to a different number and does the same thing.

0

there has to be a way to reset the random number variable to make the generator cross out that number that it just previously thought of and think of a new one.

0

Yes, so seed the random-number-generator (by calling srand(time(0))) only once ... ever ... and then just call rand() each time you need a new random number. Think of srand() as a reset() (which is what it is) ... each time you call it with a specific number, it will start over, giving you the same sequence of random numbers again.

0

Also, the numbers generated are "random" ... meaning at some point you're more likely to get a number you've seen before than one you haven't seen yet. If you want to "cross off" numbers you've seen before, you need to implement that yourself: rand() generates numbers out of a huge set, and it doesn't know about the math you're performing to map those onto a relatively small set, so even if you could tell rand() not to repeat itself, huge swaths of unique numbers would still map onto the same number in your code.

0

oh i see what is happening. I am looping the program fast enough that it doesnt have enough time to think of a random number each time it loops. How would you fix that.

0

Lol, it doesn't "think" of a new number, it's a predictable formula -- thus "pseudorandom" rather than truly random -- and it takes all the time it needs. You keep getting the same number(s) because you keep resetting it by calling srand() inside your loop. If you want to loop over the set of integers between -rr1 and rr1, in a random order, there are a couple of options. See if you can follow the example at http://www.cplusplus.com/reference/algorithm/random_shuffle/ to do what you want. BTW, cplusplus.com is an -outstanding- reference especially for the standard template library (STL).

0

ok, i built that code into my variable equation solver and now the thing wont compile. your 3rd to last post said me to put

(srand(time(0)))

in my equation solver code. that just makes C++ create a set of about 10 numbers in a given range (rr1, rr2) and it repeats itself over and over.

0

and now the thing won't compile

Heh, I still can't read minds. What error(s) are you getting, and what does the code look like in the vicinity of the problem? The great thing about compiler errors (assuming the compiler is worth anything) is that it tells you what it doesn't like and at what line. Much easier to fix than run-time problems, usually! :)

0

Finally got a chance to finish this up for now.... Sorry for the confusion about the spaces, thecoolman5! I promise I'm not trying to make you crazy. :)

If you want to avoid entering spaces, we're back to some of the previous parsing code. C++ has no way of knowing, when you're inputting a string from the user, that "22+x=5" is actually 5 tokens: the integer 22, an operator +, a variable x, an operator =, and the integer 5. We're lucky it breaks on whitespace, but you have the same problem on the other side if you want to know -what- whitespace the user typed in, or if you want to keep it for some reason.

So, for your case, you would instead use getline(cin, expressionString); , and then go through the string yourself, deciding whether the next character is part of the previous token, or indicates the start of a (potentially-single-character) new one. If this were already a solved problem, within the language, there'd be no point for you to be writing your own, right? :)

If you're not comfortable with the math conversion functions in stdlib, and want instead to handle them yourself (which is completely fine, and will certainly advance your programming skills), here is a loop over the string input above that handles positive integers:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main (void)
{
        cout << "Enter an equation: n1 op n2 op n3" << endl
             << "n values can be integers or variables" << endl;

        string expressionString;
        getline(cin, expressionString);

        // unused -- we can include this if at some point we can't keep
        // parsing the input string
        bool parseError = false;

        // keep a vector (basically "array") of string objects,
        // "vector" is from the standard template library (usually called STL)
        // we'll actually keep pairs of strings for now:
        //   a token_type string followed by the token itself
        vector<string> tokens;
        string current_token = "";

        // this is readable for now, but we should use an "enum" type later
        // to avoid programming errors (the compiler will catch typos)
        string token_type = "none";

        // simplify checking for operators
        string operators = "+-*/=";

        int i = 0;
        while (i < expressionString.length()) {

                char next_char = expressionString[i];
                if (isspace(next_char)) {
                        // space indicates end of previous token
                        if (token_type != "none") {
                                // save token we were building
                                tokens.push_back(token_type);
                                tokens.push_back(current_token);
                                // reset
                                token_type = "none";
                                current_token = "";
                        }
                        // we also don't care about it so we just skip over
                        i++;
                        continue;
                }
                if (token_type == "none") {
                        if (next_char >= '0' && next_char <= '9') {
                                token_type = "number";
                                current_token += next_char;
                        }
                        else if (operators.find(next_char) != string::npos) {
                                // operators are always single-character, so
                                // as soon as we have one, we can add it to
                                // our vector
                                token_type = "operator";
                                current_token += next_char;
                                tokens.push_back(token_type);
                                tokens.push_back(current_token);
                                // reset
                                token_type = "none";
                                current_token = "";
                        }
                        else {
                                // assume it's a variable
                                token_type = "variable";
                                current_token += next_char;
                        }
                }
                else if (token_type == "number") {
                        if (next_char >= '0' && next_char <= '9') {
                                // add the next digit to the number
                                current_token += next_char;
                        }
                        else {
                                // don't worry about what's next, we'll catch
                                // it the next time through the loop
                                // ---
                                // save token we were building
                                tokens.push_back(token_type);
                                tokens.push_back(current_token);
                                // reset
                                token_type = "none";
                                current_token = "";
                                continue;  // NOTE: without advancing i!
                        }
                }
                else if (token_type == "variable") {
                        if (operators.find(next_char) != string::npos) {
                                // assume once we've started a variable, then
                                // any character which isn't an operator is a
                                // valid continuation:  e.g. "x1", "abc", etc.
                                // ---
                                // don't worry about what's next, we'll catch
                                // it the next time through the loop
                                // ---
                                // save token we were building
                                tokens.push_back(token_type);
                                tokens.push_back(current_token);
                                // reset
                                token_type = "none";
                                current_token = "";
                                continue;  // NOTE: without advancing i!
                        }
                        else {
                                current_token += next_char;
                        }
                }
                // we need 'else if (token_type == "operator") {...}'  Why?

                i++;
        }

        if (token_type != "none") {
                // save the token that was in-progress when we ran out of
                // input
                tokens.push_back(token_type);
                tokens.push_back(current_token);
        }

        // DEBUG
        for (int j=0; j<tokens.size(); j+=2) {
                cout << "token type: " << tokens[j]
                     << ", value: \"" << tokens[j+1] << "\"" << endl;
        }

        // continue here...
        // the next step is making sure the order of the tokens makes sense
}

Note that there are still problems with this! In particular, it won't handle negative numbers (since it thinks '-' always means a subtraction operator). See if you can figure out how to fix it without my help. As a specific example, what do each of the following mean: "x-3=5" and "x+-3=5"? How would you determine whether the '-' is an operator or the beginning of a negative number? Don't forget to include the case "-2+x=5"! :)

(Another option is to consider the '-' a "unary negation operator" in front of the following number, meaning you can also have "-x" or [eventually] "-(some other expression)". In this case the parser can stay the way it is, and instead you have to identify what it means when you start looking at the list of tokens.)

0

ok, just remember that i am a beginner in C++ and that code snippet you posted doesnt make any sence to me. but i am happy that it works in my compiler. the notes that you posted helped a little bit. i also have no idea how to start the mathematical operations in that code.i am also wondering, on my original equation solver code, if you enter an equation like x + 3 - 10 = 7, the program will know that the second to last operator isnt '=' and have it start running a different section of code. here it is:

#include<iostream>
#include<cstdio>
#include<stdlib.h>
#include<sstream>
#include<cmath>
#include <ctime>
#include <cstdlib>
using namespace std;
int main (char argc)
{
    
    for(;;)
    {
           
    cout << "Variable equation solver version 2" << endl;
    cout << "Limitations: no ( and ),and no ^." << endl;
    cout << "Only variable allowed: x" << endl;
    cout << "One space between each item." << endl;
    
    char operators, operators2, operators3;
    
    string n1, n2, n3, n4;
    long double ans, ans2, ans3, ans4;
    
    (srand(time(0)));
    
    cin >> n1;
    cin >> operators;
    cin >> n2;
    cin >> operators2;
    cin >> n3;
    //i enter x + 3 - 2 = 5
for(;;)
    {
         
         
         
         //heres where it will detect that operators2 doesnt equal '='
         if(operators2 - '=')
         {
                       cin >> operators3;
                       cin >> n4;
                       //these two "cin"s should take '=' and '5' from the original equation
                       
                       if(n1 == "x")
                       {
                             long double n2_value = 0;
                             long double n3_value = 0;
                             long double n4_value = 0;
                             
                             stringstream(n2) >> n2_value;
                             stringstream(n3) >> n3_value;
                             stringstream(n4) >> n4_value;
                       
                       //start mathematical operations
                       if(operators == '+')
                       if(operators2 == '-')
                       {
                                  ans = n4_value - n2_value;
                                  ans2 = ans + n3_value;
                                  
                                  cout << "the variable equals "<<ans2<< endl;
                                  break;
                                  
                       }
                       
                       }
         }   
                       
                       
                       
                       
    // seperate the size of equation
    if(operators == '=')
    {      
           //start of original equation type "x + 3 = 2"              
          
    if(n1 == "x")
    { 
          long double n2_value = 0;
          long double n3_value = 0;
          
          stringstream(n2) >> n2_value;
          stringstream(n3) >> n3_value;



          if(operators == '+')
          {
                       ans = n3_value - n2_value;
          }
          
          if(operators == '-')
          {
                       ans = n3_value + n2_value;
          }
          
          if(operators == '/')
          {
                       ans = n3_value * n2_value;
          }
          
          if(operators == '*')
          {
                       ans = n3_value / n2_value;
          }          
          
          cout << "the variable equals "<<ans<< endl;
          break;
          
    }
    
    if(n2 == "x")
    {
          long double n1_value = 0;
          long double n3_value = 0;
          
          stringstream(n1) >> n1_value;
          stringstream(n3) >> n3_value;
          
          
          if(operators == '+')
          {
                       ans = n3_value - n1_value;
          }
          
          if(operators == '-')
          {
                       ans = n3_value + n1_value;
          }
          
          if(operators == '/')
          {
                       ans = n1_value / n3_value;
          }
          
          if(operators == '*')
          {
                       ans = n3_value / n1_value;
          }
          cout << "the variable equals "<<ans<< endl;
          break;
         
          }
          
          if(n3 == "x")
          {
                long double n1_value = 0;
                long double n2_value = 0;
          
                stringstream(n1) >> n1_value;
                stringstream(n2) >> n2_value;
          

                
                if(operators == '+')
          {
                       ans = n1_value + n2_value;
          }
          
          if(operators == '-')
          {
                       ans = n1_value - n2_value;
          }
          
          if(operators == '/')
          {
                       ans = n1_value / n2_value;
          }
          
          if(operators == '*')
          {
                       ans = n1_value * n2_value;
          }
          cout << "the variable equals "<<ans<< endl;
          break;
          }
          }
          system("pause");
          system("cls");
          }
          
    }
}

and for some reason, when i enter an equation like x + 3 = 2, the program just starts running an infinite loop of

system("pause"); //and 
system("cls");
This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.