0

I have been trying to learn argc and argv. But to do that, I have been trying to implement it into a calculator with an extra calculator portion if argv doesn't have any data. But I can't seem to figure out how to do it.

Here's the calculator before argc/argv:

#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
  double num1, num2;
  char op;
  char response('y');
  cout << " /=========================\\" << endl;
  cout << "( Operators are: +  -  *  / )" << endl;
  cout << " \\=========================/" << endl;
 do {
  cout << "> ";
  cin >> num1;
  cin >> op;
  cin >> num2;

  double result;
   if(cin.fail()) {
    cout << "ERROR" << endl;
        cout << "Either, you put a letter, or the calculator can\'t calculate." << endl;
        break;
   };
   if(op == '+') {
        result = num1 + num2;
   } else if(op == '-') {
        result = num1 - num2;
   } else if(op == '/') {
        result = num1 / num2;
   } else if(op == '*') {
        result = num1 * num2;
   } else {
        cout << "Invalid Operator" << endl;
        cout << "Exit code: ";
   };
  cout << result << endl;
      cout << "Do you want to enter another calculation? (Y/N) ";
    cin >> response;
  } while (response == 'Y' || response == 'y');
    return 0;
}

and here's it afterwards:

#include <iostream>
#include <string>
#include <sstream>
#include <cmath>
using namespace std;
int main(int argc, char** argv) {
  if(*argv[1] == '-t') {
  double num1, num2;
  char op;
  char response('y');
  cout << " /=========================\\" << endl;
  cout << "( Operators are: +  -  *  / )" << endl;
  cout << " \\=========================/" << endl;
 do {
  cout << "> ";
  cin >> num1;
  cin >> op;
  cin >> num2;

  double result;
   if(cin.fail()) {
    cout << "ERROR" << endl;
        cout << "Either, you put a letter, or the calculator can\'t calculate." << endl;
        break;
   };
   if(op == '+') {
        result = num1 + num2;
   } else if(op == '-') {
        result = num1 - num2;
   } else if(op == '/') {
        result = num1 / num2;
   } else if(op == '*') {
        result = num1 * num2;
   } else {
        cout << "Invalid Operator" << endl;
        cout << "Exit code: ";
   };
  cout << result << endl;
      cout << "Do you want to enter another calculation? (Y/N) ";
    cin >> response;
  } while (response == 'Y' || response == 'y');
    return 0;
  } else {
        double result;
        int num1 = *argv[1] - 48;
        int num2 = *argv[3] - 48;
        if(*argv[3] == '+') {
                result = num1 + num2;
        }
        cout << result << endl;
  }
}

I'm very confused on how I can do it because if It has no response it give "Segmentation Fault" on my Linux terminal...

Ken White
  • 123,280
  • 14
  • 225
  • 444
0NeXt
  • 1
  • 2
  • always check `argc` first, because that's the number of parameters in the `argv` array. Never index `argv` by more than `argc-1`, since arrays are 0-based. – Chris Uzdavinis Nov 07 '22 at 05:18
  • `argc` is the argument count. You have to check it before you try to use `argv{}`. The only thing guaranteed to be there is `argv[0]`, which is the fully-qualified pathname to the application itself. You can't read `argv[1]` without having checked to make sure it exists by checking `argc`. – Ken White Nov 07 '22 at 05:21
  • @ChrisUzdavinis Not true. The standard requires `argc` be non-negative and that `argv` points at the first element of an array with `argc + 1` pointers, and the last one (i.e. `argv[argc]`) will be equal to `NULL`. This does mean that `argv[0]` can always be evaluated but that it may be `NULL` (in which case it should not be dereferenced). – Peter Nov 07 '22 at 05:52
  • Note that `'-t'` is a `char` literal, not a string literal. But even if you did `"-t"`, you can't compare `char*` C-style strings by `==`, since that's checking for pointer equality not actual string equality. (Although actually you're looking at `*argv[1]`, which is itself a single `char`, which is how this compiles at all.) – Nathan Pierson Nov 07 '22 at 05:57
  • Why make your attempt so complicated? Forget the calculator. Instead, try a program that outputs either "argv has data" or "argv does not have data" as appropriate. The same basic setup as you have now for arguments, but abstracting away what would be the calculator. (The calculator can be added later, once you have the command line processing working.) – JaMiT Nov 07 '22 at 06:11
  • @Peter You're right, you can read the null pointer if you want, but I didn't assume that was the intent since the pointers are being dereferenced without checking for null, or range at all. The code in the question is _not_ just indexing `argv[0]`, but is reading `argv[1]` and `argv[3]` without any range checks and dereferencing them. I could have been more pedantic and said not to _dereference_ the pointer past argc-1, or read past argv[argc], but that's more detail than necessary in most cases and obscuring the main point: RANGE CHECK BEFORE READING. – Chris Uzdavinis Nov 08 '22 at 00:22

0 Answers0