0

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;

}
xyzzy
  • 23
  • 1
  • 4
  • 1
    How are you calling getCommand? How are you getting the string? – Collin Mar 12 '12 at 14:30
  • 2
    If I understand your question, I *think* you should be passing that string in to `getCommand()` as the `inputstring` parameter (which your function signature takes, but you do nothing with). – Moo-Juice Mar 12 '12 at 14:33
  • Oh whoops. I must have left that in the signature as I've been tweaking this code. As mentioned, I considered adding the string to the function, but seeing as it's really the ONLY string the function will ever be reading from I don't like that solution as much. (I suppose if it ain't broke though...) – xyzzy Mar 12 '12 at 14:39

1 Answers1

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"
}
twain249
  • 5,666
  • 1
  • 21
  • 26
  • I'd paste the code but it's rather lengthy, and I don't know what parts might be relevant. I'll try and cut it down though, it's about 200 lines. – xyzzy Mar 12 '12 at 14:41
  • Just make sure you paste any code that has the variable in question in it. – twain249 Mar 12 '12 at 14:48
  • Just earlier today my friend (working on a similar project) had a bug that we found was due to his "endl" placements... since then I've been very wary of what might be relevant code :) – xyzzy Mar 12 '12 at 14:51
  • 2 things. In your first set of code (the one without the global) you are using `stdinstring` in `getCommand()` where the name of the parameter is `inputstring` you should use `inputstring`. Second I wrote what I believe is happening in the getCommand method in my answer. – twain249 Mar 12 '12 at 15:01
  • stdinstring = "a"; was just me tweaking around seeing if I could get the garbage characters that were appearing to go away. Also, I neglected to add my input to this program, which has pleny of parens... heh. Because of where getCommand is run it's basically guaranteed to never get -1 for the rfind. At any rate I found a major flaw in what I was doing - I was trying to read stdinstring before it was fully constructed... – xyzzy Mar 12 '12 at 15:18
  • As far as I can tell the only place that writes to `stdinstring` is `//Write the character if (write) {stdinstring.push_back(c_lookaround[1]);}` which should mean that the `stdinstring` is only added to never subtracted from. Also your `getCommand()` method returns a substring of the `stdinstring` but you never set that returned string to anything. – twain249 Mar 12 '12 at 15:25
  • Haha, I really uploaded a quickly-becoming obsolete version of my code. I managed to get the wheels turning again after separating out the code that was reading stdinstring from that which was writing -.-' – xyzzy Mar 12 '12 at 18:24
  • Marking yours as the answer though. As a side note, upon adding the stream argument I've found new uses for this function... I thought it was just going to be grabbing statements out of the main stdiostring but it turns out it's far more useful than I thought to be able to grab from substrings. Code reuse saves the day again! – xyzzy Mar 12 '12 at 18:26