C++: Easiest way to access main variable from func

2019-03-05 08:04发布

问题:

I'm currently dealing with a string initialized in main() that for some reason freaks out (it becomes a string of non-characters) if I try and make it global. I'm wondering whether I can have a function declared in the program access this variable... the function itself will only ever be executed in main or functions called from main, but the compiler doesn't see the variable name until main() is reached.

Here is a skinny version of the relevant code:

string getCommand(int input_pos,string inputstring)
{
int temp_paren=0;
int begin_pos = stdinstring.rfind("(",input_pos);
int len = 0;
while (temp_paren>0 && len < 10)
 {
 if (stdinstring.substr(begin_pos+len,1)=="(") {temp_paren++;}
 if (stdinstring.substr(begin_pos+len,1)==")") {temp_paren--;}
 len++;
 }
 return stdinstring.substr(begin_pos,len);
}

int main(void) {

string stdinstring = ""; 
}

I've been considering forward declarations, passing the variable to the function by hand each time I use it, even making a class to hold that variable... What would be the simplest way to solve this problem? Ideally I would have enough time to make it a global variable and figure out where/why that's going wrong, but I just need to get this done. Thanks for any and all help.


EDIT: For anyone interested: This is what happens if I try and make the string a global. All of the characters become "" (dunno if that's even visible)


EDIT EDIT: Okay, here's a more complete version of my code. Also, the symbols I tried pasting above were boxes with what appeared to be "0 0 0 1" (ASCII character code?)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<stdint.h>
//#include<regex>

#define PI M_PI
#define VERBOSE 1
using namespace std;

string stdinstring; 

template <class dataclass> 
struct linkm {
  dataclass value;
  linkm *next;
};

template <class dataclass> 
class linklist 
{
  public:
    linklist()
      {top = NULL;}
    ~linklist() 
      {}
    void push(dataclass num)
      {
      linkm<dataclass> *temp = new linkm<dataclass>;
      temp->value = num;
      temp->next = top;
      top = temp;
      } 
    dataclass pop()
      {
      if (top == NULL) 
        return 0;
      linkm<dataclass> * temp;
      temp = top;
      dataclass value;
      value = temp->value;
      top = temp->next;
      delete temp;
      return value;
      }
    bool isEmpty()
      {
      if (top == NULL) 
        return 1;
      return 0;
      }
  private:
    linkm<dataclass> *top; 
};

double evaluateExpression(string expression)
{
// sample expression : (* (/ a 1) (+ b 2))
     if (expression.substr(0,2)=="(+") {cout << "add found"<<endl;}
else if (expression.substr(0,2)=="(-") {cout << "sub found"<<endl;}
else if (expression.substr(0,2)=="(*") {cout << "mult found"<<endl;}
else if (expression.substr(0,2)=="(/") {cout << "div found"<<endl;}
else if (expression.substr(0,2)=="(sin") {cout << "sin found"<<endl;}
else if (expression.substr(0,2)=="(cos") {cout << "cos found"<<endl;}
else {cout << "Error: invalid operation";} // or is it just a number?
}

string getCommand(int input_pos,string inputstring)
{
int temp_paren=0;
int begin_pos = stdinstring.rfind("(",input_pos);
int len = 0;
while (temp_paren>0 && len < 10)
 {
 if (stdinstring.substr(begin_pos+len,1)=="(") {temp_paren++;}
 if (stdinstring.substr(begin_pos+len,1)==")") {temp_paren--;}
 len++;
 }
 return stdinstring.substr(begin_pos,len);
}

class symContainer
{
public:
string index[500];
float value[500];
int currindex;

symContainer () { currindex = 0 ; }

void add(string id,float invalue)
{
index[currindex] = id;
value[currindex] = invalue;
currindex++;
}

float get(string id)
{
int i=0;
while (i<currindex)
 {
 if(id==index[i]) {return value[i];}
 i++;
 }
 cout << "Invalid input - an unassigned symbol was requested:" << id << endl;
 exit(2);
}

};


struct transform { int type; double arguments[4]; } ;
struct point { double x; double y; } ;
struct drawing { linklist<point> points; linklist<transform> transforms; void applyTransforms(linklist<transform> * trsptr) {}  } ; 
struct group : public drawing { linklist<int> drawings; void transform(linklist<transform> * trsptr) {} } ;
struct symbol {string index; double value;};

char getNext() { //for the lookaround function. has hard-filters, like replacing newlines/tabs with spaces
char temp = getchar(); 
if (temp=='\n') {temp=' ';}
if (temp=='\t') {temp=' ';}
return temp;
}

int main(void) {

stdinstring="a";

char command[20], args[2048];
int commandindex=0;     //'i' for what command we're on
int stdinsize=2;
double argsArray[8];
bool filled=0;
int parenlevel = 0;
symContainer symbol;

//1 is the character that will be written at the end of each loop. 0 and 2 are 1 char ahead/behind, respectively
char c_lookaround[2]; 
c_lookaround[0]=NULL;
c_lookaround[1]=getNext();
c_lookaround[2]=getNext();

unsigned long i=0;

bool write=0;
while( c_lookaround[2] != EOF )
{ 
write=1;
// Lookaround logic goes here. (Clearing duplicate whitespaces, newlines, and the like)

while (                         c_lookaround[1]==' '  && c_lookaround[2]==' ' ) {c_lookaround[2]=getNext();}
while (c_lookaround[0]=='('  && c_lookaround[1]==' '                          ) {c_lookaround[1]=c_lookaround[2]; c_lookaround[2]=getNext();}
while (                         c_lookaround[1]==' '  && c_lookaround[2]==')' ) {c_lookaround[1]=c_lookaround[2]; c_lookaround[2]=getNext();}
while (c_lookaround[0]==NULL && c_lookaround[1]==' '                          ) {c_lookaround[1]=c_lookaround[2]; c_lookaround[2]=getNext();}
//while (c_lookaround[0]==')'  && c_lookaround[1]==' '  && c_lookaround[2]=='(' ) {c_lookaround[1]=c_lookaround[2]; c_lookaround[2]=getNext();}
//while (c_lookaround[0]==')'  && c_lookaround[1]==' '  && c_lookaround[2]=='\0' ) {cout<<"aa";c_lookaround[1]=c_lookaround[2]; c_lookaround[2]=getNext();}

if (c_lookaround[0]=='('  && c_lookaround[1]==':'  && c_lookaround[2]=='=') 
 {
    getCommand(i,stdinstring);
 }

//Determine current parentheses level
if (c_lookaround[1] == '(') { parenlevel++;}
if (parenlevel==0) {write=0;}
if (c_lookaround[1] == ')') { parenlevel--;}

//Write the character 
if (write) {stdinstring.push_back(c_lookaround[1]);}
cout << stdinstring<< endl;

//Advance the tape!
i++;
c_lookaround[0]=c_lookaround[1];
c_lookaround[1]=c_lookaround[2];
c_lookaround[2]=getNext();
}

stdinsize = i;

}

回答1:

if you're calling getCommand() from main() you should be able to pass the variable.

int main(void) {
    string stdinstring = ""; 
    string answer = getCommand(0, stdinstring);
}

If you are calling getCommand() from somewhere else you'll have to pass the variable to that function from main() and then to getCommand(). Also you should be able to make it global but without the code I don't know why you weren't able to.

//stdinstring = "a" in the case (how is this set to anything but it?
string getCommand(int input_pos,string inputstring)
{
   int temp_paren=0;
   int begin_pos = stdinstring.rfind("(",input_pos); //This equals -1 
   int len = 0;
   while (temp_paren>0 && len < 10) //There is no ( so the loop terminates with len=10
   {
      if (stdinstring.substr(begin_pos+len,1)=="(") {temp_paren++;}
      if (stdinstring.substr(begin_pos+len,1)==")") {temp_paren--;}
     len++;
   }
   return stdinstring.substr(begin_pos,len); //returns the first 10 chars of stdinstring which would be "a"
}