Hello all,

My assignment is to write a quadratic equation solver. I have written the function, and it compiles well. However that is not the issue. The requirements are that it follows a command line interface specification as follows:

<program name> -r <quadratic equation>

In other words, the user is to enter "-r" followed by the equation, and the program will then output the roots as two numbers on the next line, and that's it. That means I can't have any other expressions like "Enter the value of a..." or "Enter the value of b..." and then cin my b variable. How do I write the piece of code so that all the user has to do is type "-r" and then the equation, and this will call my function and output the results? Any suggestions or guides..?

Seems to me you can't actually solve the equation without some values. Therefore, ask your instructor for more details.

I find that C++ textbooks in general completely ignore the topic of command line arguments, so I won't tell you to look in the book.

Here are a few links that may help you to understand how to do this:

http://www.cprogramming.com/tutorial/lesson14.html
http://malun1.mala.bc.ca:8080/~wesselsd/csci161/notes/args.html

The short version is that argv[] is an array of C-style strings (char array based, null terminated) where the first (index 0) is the program name.

You need to check the next string to verify it is "-r" before your program continues to then read the a, b, c values from the remaining strings.

Val

Thanks Val. That will work finely. However, when I wrote my code for my quadratic, I neglected something quite important, actually. Please bear in mind that I am a beginner at this. Let me see if I can explain.

The first argument will automatically be the program name, followed by the command the use will type in. I organized it such that when the use types in "-r", the program will call my function to calculate the roots. Here is my problem. I'm not sure how to write the code such that the program will automatically read the values of a, b and c and do the required computation. My function (which I've aptly named Root_Quadratic") basically acknowledges integers a, b and c and then via an if loop computes the roots and displays the roots. But the step to get my program to KNOW which values are a, b and c, I'm not sure. Remember that I'm writing the entire quadratic equation as my third argument (argv[2]). Once again, some guides will be quite helpful here. I know I'm missing something quite simple, but I just cant figure it out.

It would help if you would post the code you have. As I understand what you're trying to do, you will have to treat your inputs from the command line as separate arguments ( argv[2], argv[3] and argv[4]). Each space delimited sequence on the command line is a separate argument.

And keep in mind, these inputs from the command line are strings. You will have to convert them to the numeric values they represent. If you are using only integer values, the the atoi( ) function will be handy.

Val

The code is basic. (I dont have it with me. My apologies.)

void Root_Quadratic ();

    int a;
    int b;
    int c;
    double r1;
    double rt2;
    double d_crim;

    d_crim = pow(b,2) - (4 * a * c);
    r1 = (-b + sqrt(d_crim)) / (2 * a);
    r2 = (-b - sqrt(d_crim)) / (2 * a);

   cout << r1 << r2 << endl;

Not that I'm recalling from memory, so there may be some stuff I'm forgetting, but I believe I have the gist of it. Ignore the syntactical errors I made. My issue is that the function declares a, b and c as integers and so on. But what do I need to write again such that when the command -r at argv[1] and the quadratic equation at argv[2] are typed and this function is called, the program will automatically know which values of the quadratic equation the user typed are a,b and c.

Think of it this way:
It's similar to other simple programs which find the root of a quadratic with the exception that there is no

cout<< "Enter the value of a:" <<endl;
cout<< "Enter the value of b:" <<endl;
cout<< "Enter the value of c:" <<endl;

And then the user enters these values and the program uses a formula (similar to that above) and computes two roots and then displays these roots. My code is similar WITH THE EXCEPTION that the user is not prompted to enter these values hence the program must know which value is which so at to manipulate these values in the formula. That's the problem.

Gerron.

Maybe I can write an algorithm (well sort of) to explain what I\ve got so far, in terms of how this thing works.

int main (int argc, char* argv[])  <-- obvious by now


//I'm thinking to place the coefficients a, b and c into an array of size 3 and when the command is called, the program will use the values from here to work out the roots.


//Initialize variables here


int coeff[3];
int quadratic;


if(strcmp (argv[1], "-help") == 0) {
cout << help menu <<endl;    (the help menu is not available to me right now, so
we'll just work with the bad syntax
}


if(strcmp (argv[1], "-r") == 0) {argv[2] = quadratic ??

(at this point I would insert the function to find the roots of the quadratic??)

Herein lies two problems.
1. The problem I mentioned before about the values a, b and c.
2. Does the line if placed in bold make any sense?

Edited 3 Years Ago by happygeek: fixed formatting

1. The problem I mentioned before about the values a, b and c.
2. Does the line if placed in bold make any sense?

1 - Consider what the argv array of strings looks like if I enter the following on the command line:
C:> find_roots -r 3 15 9 <enter>

argv[0] = "find_roots"
argv[1] = "-r"
argv[2] = "3"
argv[3] = "15"
argv[4] = "9"

Each of these is a C-style string- an array of characters have have a NULL terminator ( '\0' ) after the content (that is, argv[1] has content '-' 'r' '\0' )

If you want to put the three number arguments into your coefficient array (integers) you will need to convert each of the strings to the numeric value they represent. The atoi( ) function can do this for you (look it up.) Once you've placed the values in the array, be sure that you pass it as a parameter to your function.

2 No, this line makes no sense. In the first place, you should not change what's in your argv[] array strings - you never know how big the arrays are that hold the data. And the line, as you wrote, doesn't seem like it would do anything approaching what you want. Rather, once you've put the argument values into the coefficient array, simply call your function, like root_quadratic( coefficient, r1, r2 ); Structure your function so that the roots you seek are placed in the r1 and r2 parameters.

And, for completeness sake, you might have the function return a value that indicates if it could successfully find roots. What happens if the value of A is 0? Or if the discriminant is negative?

When it comes to dealing with imaginary numbers, I usually leave that to my imaginary friend.

Val

Thanks Val. I understand when you have just the COEFFICIENTS of a, b and c being entered by the user. However, the specs required the ENTIRE quadratic equation to be entered by the user i.e. the inclusion of a single variable be it x or p or q or whatever. Any suggestions?

On another note, can one suggest how to go about writing functions to integrate and differentiate a quadratic equation/expression. This would involve both coefficient and variable, so once again any suggestions.

do you mean the user is supposed to enter something like:

c:>root_finder -r 3x^2+5x-3=9 <enter>

Oh wow, is that a problem of a different color. Sounds like something more advanced that where it appears you are in learning to program, so far.

Please clarify.

Val

I should have given an example, but yes...your example says it. The user types the entire equation e.g. 2x^2 + 3x + 5.

Basically, what I'm thinking is I need to come up with some kind of code which, when the user types in the quadratic equation, will identify a as the coefficient of x^2 (in this case 2), b as the coefficient of x (in this case 3) and c as the constant (=5). The program should then place it into the array [a b c] and then in the function, a pointer will extract the elements and manipulate them into the computational formula. It sound allright, but the code is heavy. I just cant figure it out, and I'm not too sure that an array would work. Maybe a vector?

What about the other aspects? Integral and differential of the equation? Any thoughts?

This is an added level of complexity, an added step to your problem. However, everything we've discussed previously still applies. Your root finding function should still work as I proposed before.

Now you need a function to extract the a, b, c values from a string. Here we need first to ensure how the string is entered at the command line.

If the user enters the expression all packed together, as in 3x^2+9x-5, we will get the entire string as the argv[2]. If the user enters any spaces, you get more argv[] strings. If the user surrounds the expression with double quotes, we get one string regardless of spacing, such as "3x^2 + 9x - 5"

Your problem, in a separate string parsing function, is to read digits (and leading negative sign, if present) till you find the first x, convert them to the A value. Skip charaters till you find the + or -, then find digit characters again till x, convert and store to B value. Again skip characters till you find + or -, read final digit characters. Now convert to the C value. And away you go.

I'll leave it to someone more mathematically minded to help with coding the calculus.

Hi, I have another issue. Thanks, by the way Val. I'm currently working on a function to extract a, b and c from the string and place it in an array. Let's hope it works.

My issue is this:
Provided I've written my main function Root_Quadratic, how do I tell the program that the quadratic equation to be solved is in the element argv[2]? Obviously
string quadratic = a*x^2 + b*x + c;
argv[2] = quadratic
wouldn't work.

I in my main function I called for Root_Quadratic() when argv[1] is "-r" ( I used strcmp to do this.) So my thinking process is this:
-r is entered, the function is called, program goes to this function and should execute it. the quadratic is in the next element in the arg array at argv[2], how do I tell my program that?

I know I have a lot of question of something that might be simple, but I'm learning here. And resources are limited where I am right now.

In a test program write this:

cout << argv[2] << endl;

and see what happens. argv[2] IS the equation in the form a C style null terminated string. You can copy this to another C style string using strcpy() or you could initialize another C style string with argv[2] if you don't like using that name for the equation. Alternatively, I believe you can use argv[2] to initialize an STL string if you want, and you may be able to assign argv[2] to an STL string, though I'm not as sure about that one.

OK, my approach to setting up your program would be something like this:

if( argc == 3 )   //testing enough args were entered at command line
    if( strcmp( argv[1], "-r" )  == 0 )  //we're looking for roots
    {
          extract_coeffs( coeff_arr, argv[2] );  //parse the string,put a, b, c into array
          if( root_finder( coeff_array, r1, r2 ) ) //could real roots be found
              display_roots( argv[2], r1, r2 );
          else
              //display some error message
     }

where extract_coeffs( ) parses the argv[2] string to get the numeric values of a, b, c
and where root_finder solves for the roots, if the values a, b, c will provide for such solution. It returns true if successful, false if not.

As i figured, the function to split the string into an array and then use the values in my array to do computations is complex...at least I think it so. Here's what I have. My explanations follow:

//this first piece initializes the string. Basically it splits the string and places it into a vector called coeff1. Mt delimiters are +, - and = and this will be implemented in my coeff_b function which I'm having problems with. Does this even make sense?
string s;
vector<string> find_coeff (const string& s)
{
vector<string>  coeff1;
typedef string::const iterator it;
it b1 = s.begin ()
it b2 = s.end ()
 
while (b1 !=e1) {
b1 = coeff_b (b1, e1)
 
if (b1 !=e1) {
it b2 = coeff_e (b1, e1)
 
coeff1.push_back(b1, b2)
b1 = b2;
}
}
return coeff1;
}
 
//I then have to write functions for the predicates coeff_b and coeff_e
 
coeff_e(b1, e1)
string :: const_iterator
coeff_e (const_iterator b1, const_iterator e1)
{
return find_if (b1, e1, v_coeff)
 
//Now I need to write a function for v_coeff predicate to return false if the characters entered are not valid. Can you tell me if this makes sense?
 
bool coeff2 (char d)
{
static const string val1 = "0 1 2 3 4 5 6 7 8 9"
return (isalnum (c) || find val1.begin (), val1.end (), d) !=val1.end() );

My aim is to split a quadratic equation
ax^2 + bx + c = 0,
and pull out a, b and c.
My code above is expected to use iterators b1 and e1 to go through the string and based on my function coeff_b and coeff_e will take these out and put them into a vector called coeff1; at that point I would prefer to use an array. How do I place the vector values into an array?

>>return false if the characters entered are not valid

Validating input in this setting is not straightforward.

>>How do I place the vector values into an array?

A loop to assign each char in the vector into the array one by one is the usual way. The big question is why bother doing this?

To parse out the a, b, and c from input like this:
ax^2+bx+c
I'd first declare three string variables, string1, string2, string3. Then I'd read the input string char by char putting each char read up to but not including the first alphabetical char into string1. Then I'd put all characters from the 3rd char after the first alphabetical char up to but not including the second alphabetical char into string2. Then I'd read the rest of the input string into string3. I'd then look at the first element of each string and if it was a + sign, I'd remove it. Finally, I'd convert string1, string2 and string3 into int variables called a, b, c.

Hmmm...I decided to write a function which intiated two iterators b and e and then use the find_if function and the isdigit function as the predicate to locate a digit. Iterators b and e will search for the beginning of digit and end of digit respectively and copy what is between both iterators into a vector. I then placed all elements of the vector into an array .

sounds pretty much the same as my description except using the Standard Template Library (with find_if, iterators, and vectors) instead of basic C/C++ style processes like if statements, [] operators and an array (if you don't want to use individual variables for the three strings developed). If it gets where you want to go without too many distractions, go for it.

This article has been dead for over six months. Start a new discussion instead.