mercredi 19 avril 2017

Undefined Symbols and use of undeclared identifier

I am a new C++ programmer and I have one C++ file that I am trying to compile on my MacBook Pro with macOS Sierra installed. When I first tried to compile it with:

g++ -std=c++11 Main.cpp -o rpns 

I got this error:

Undefined symbols for architecture x86_64:
"eval_expr(std::__1::stack<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::deque<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >&, std::__1::stack<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::deque<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >&, std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, int> > >)", referenced from:
  _main in Main-2c97f0.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I then found some answers that said I should compile like this:

g++ -std=c++11 -stdlib=libstdc++ Main.cpp -o rpns

I then got this error:

Main.cpp:105:11: error: use of undeclared identifier 'stoi'
  ind = stoi(n, &sz);
      ^
Main.cpp:120:11: error: use of undeclared identifier 'stoi'
  ind = stoi(n, &sz);
      ^
Main.cpp:133:10: error: use of undeclared identifier 'to_string'
  return to_string(len);
     ^
Main.cpp:138:10: error: use of undeclared identifier 'to_string'
  return to_string(ind);
     ^
Main.cpp:146:9: error: use of undeclared identifier 'stoi'
  x = stoi(num1, &sz);
    ^
Main.cpp:147:9: error: use of undeclared identifier 'stoi'
  y = stoi(num2, &sz);
    ^
Main.cpp:155:11: error: use of undeclared identifier 'to_string'
  return to_string(x + y);
           ^
Main.cpp:163:9: error: use of undeclared identifier 'stoi'
  x = stoi(num1, &sz);
    ^
Main.cpp:164:9: error: use of undeclared identifier 'stoi'
  y = stoi(num2, &sz);
    ^
Main.cpp:172:11: error: use of undeclared identifier 'to_string'
  return to_string(x - y);
           ^
10 errors generated.

Here is my code for Main.cpp:

#include <iostream>
#include <string>
#include <stack>
#include <vector>
#include <map>
#include <stdexcept>
using namespace std;

void init_map(map<string, int>& operatorToNumOperands);
string eval_expr(stack<string> &operands, stack<string> &operators, map<string, int> optor_to_num_opnd);
string operator_tilde(const string s1, const string s2);

string operator_right(const string s, const string n);

string operator_left(const string s, const string n);

string operator_len(const string& s);

string operator_find(const string& s, const string& f);

string operator_plus(const string num1, const string num2);

string operator_minus(const string num1, const string num2);

int main() {
  map<string, int> operatorToNumOperands;
  init_map(operatorToNumOperands);
  stack<string> opand_stack;
  stack<string> optor_stack;
  string token;
  while(getline(cin, token)) {
    if(token =="")
      break;
    if(operatorToNumOperands.count(token)) {
      optor_stack.push(token);
    } else { 
      opand_stack.push(token);
    }
  }
  string expr_val = eval_expr(opand_stack, optor_stack, operatorToNumOperands);
  cout << expr_val << endl;
  return 0;
}


void init_map(map<string, int>& operatorToNumOperands) {
  operatorToNumOperands.insert({"~", 2});
  operatorToNumOperands.insert({"->", 2});
  operatorToNumOperands.insert({"<-", 2});
  operatorToNumOperands.insert({"#",1});
  operatorToNumOperands.insert({"?",2});
  operatorToNumOperands.insert({"+",2});
  operatorToNumOperands.insert({"-",2});
}

string eval_expr(stack<string> &operands, stack<string> &operators, const map<string, int> &optor_to_num_opnd) {
  while(!operators.empty()) {
    int numOperands = optor_to_num_opnd.at(operators.top());
    vector<string> opands;
    while(numOperands > 0) {
      if(operands.empty())
        throw "not enough arguments given for: '" + operators.top() + "' operator";
      opands.push_back(string(operators.top()));
      numOperands--;
    }
    string expr_val = "";
    try {
        if(operators.top() == "~") {
          expr_val = operator_tilde(opands[1], opands[0]);
        } else if(operators.top() == "->") {
          expr_val = operator_right(opands[1], opands[0]);
        } else if(operators.top() == "<-") {
          expr_val = operator_left(opands[1], opands[0]);
        } else if(operators.top() == "#") {
          expr_val = operator_len(opands[0]);
        } else if(operators.top() == "?") {
          expr_val = operator_find(opands[1], opands[0]);
        } else if(operators.top() == "+") {
          expr_val = operator_plus(opands[1], opands[0]);
        } else  { 
          expr_val = operator_minus(opands[1], opands[0]);
        }
        operators.pop();
    } catch (const invalid_argument& ia) {
        throw invalid_argument("InvalidArgumentError: " + string(ia.what()) + "\n");
    } catch (const out_of_range& oor) {
        throw out_of_range("OutofRangeError" + string(oor.what()) + "\n");
    }
    operands.push(expr_val);
  }
  return string(operands.top());
}

string operator_tilde(const string s1, const string s2 ) {
  return s1 + s2;
}

string operator_right(const string s, const string n) {
  int ind;
  try {
    string::size_type sz;
    ind = stoi(n, &sz);
    if(!sz)
      throw "InvalidArgumentError: 2nd operand for '->' must be numeric.";
  } catch (const invalid_argument& ia) {
      throw invalid_argument("InvalidArgumentError: " + string(ia.what()) + "\n");
  } catch (const out_of_range& oor) {
      throw out_of_range("OutofRangeError" + string(oor.what()) + '\n');
  }
  return s.substr(0,ind);
}

string operator_left(const string s, const string n) {
  int ind;
  try {
    string::size_type sz;
    ind = stoi(n, &sz);
    if(!sz)
      throw "InvalidArgumentError: 2nd operand for operator '<-' must be numeric.";
  } catch (const invalid_argument& ia) {
      throw invalid_argument("InvalidArgumentError: " + string(ia.what()) + "\n");
  } catch (const out_of_range& oor) {
      throw out_of_range("OutofRangeError" + string(oor.what()) + '\n');
  }
  return s.substr(s.size() - ind);
}

string operator_len(const string& s) {
  unsigned int len = s.size();
  return to_string(len);
}

string operator_find(const string& s, const string& f) {
  unsigned int ind = s.find(f);
  return to_string(ind);
}

string operator_plus(const string num1, const string num2) {
  int x;
  int y;
  try {
    string::size_type sz;
    x = stoi(num1, &sz);
    y = stoi(num2, &sz);
    if(!sz)
      throw "InvalidArgumentError: both operands for operator '+' must be numeric.";
    } catch (const invalid_argument& ia) {
      throw invalid_argument("InvalidArgumentError: " + string(ia.what()) + "\n");
    } catch (const out_of_range& oor) {
      throw out_of_range("OutofRangeError" + string(oor.what()) + '\n');
    }
    return to_string(x + y);
}

string operator_minus(const string num1, const string num2) {
  int x;
  int y;
  try {
    string::size_type sz;
    x = stoi(num1, &sz);
    y = stoi(num2, &sz);
    if(!sz)
      throw "InvalidArgumentError: both operands for operator '-' must be numeric.";
    } catch (const invalid_argument& ia) {
      throw invalid_argument("InvalidArgumentError: " + string(ia.what()) + "\n");
    } catch (const out_of_range& oor) {
      throw out_of_range("OutofRangeError" + string(oor.what()) + '\n');
    }
    return to_string(x - y);
}

I've been stuck on these two errors for hours. Thanks in advance for any help.

Aucun commentaire:

Enregistrer un commentaire