c++/xcode function parameter passing

Discussion in 'Mac Programming' started by chaos2828, Mar 24, 2008.

  1. macrumors newbie

    Joined:
    Mar 7, 2008
    Location:
    Michigan
    #1
    Hello, all,

    I'm learning about passing function parameters in c++, but I'm having no luck doing so with the code below. Has anyone else had difficulties passing such things with xcode? Or have I missed something really dumb in the code?

    (I've already turned this assignment in, but need to figure out how to do this properly for future assingments.)

    Thanks for looking.

    Code:
     
    #include <iostream>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    char get_Data(ifstream& in_File, char& romanLet); /* gets Roman numbers,     character by character, from input file*/
    
    void print_Roman(ofstream& out_File, char& romanLet); /* prints each Roman character to out_File as it's read into file*/
    
    
    int main ()
    {
    
    // Declare variables
    
    char roman1; 
    int deci;
    int decimal1;
    int decimal2; 
    char operator;
    int mathResult;
    
    ifstream mp4romanletrdata;
    ofstream outRoman;
    
    // Open file
    	mp4romanletrdata.open("/Users/rob/getDataFunction/build/Release/mp4romanletrdata");
    	outRoman.open("outRoman"); 
    	
    // Test opening
    	if (!mp4romanletrdata || !outRoman)
    	{ cout << "Unable to open files." << endl;
    	  cout << "Program terminates." << endl; 
    	}
    
    
     
    do {
    	 outRoman << "The first Roman Number is " ;
    	
    	 // Calculate first number 
    		do {
    			roman1 = get_Data(mp4romanletrdata, roman1);
    		if (roman1 != ' ')
    			print_Roman(outRoman, roman1);
    			decimal1 += convert_Roman_to_Decimal(roman1, deci);
    					}
    		while (roman1 != ' ');
    			outRoman <<  " (   " << decimal1 << "   )." << endl;
    	
    	 outRoman << "The second Roman Number is " ;		
    	
    .// there's more to the program, but this is the beginning of my trouble
    .
    .
    return 0;
    }
    /*****************************************************
     BEGIN 
     get_Data Function:
    *****************************************************/
    char get_Data(ifstream& in_File, char& romanLet)
    {
    
    char romanLetter; 
    
    	
    // Get data char from input file
    
    if (in_File.get(romanLetter))
    	return romanLetter;	
    else return ' ';
    
    
    }/****************************************************
      END 
      get_Data
    ******************************************************/
    
    
    
    /*****************************************************
     BEGIN 
     void print_Roman:
     *****************************************************/
    
    void print_Roman(ofstream& out_File, char& romanLet)
    
    {
    char romanLetter; // sent from get_Data
    
    out_File << romanLetter; // decimal value totaled in main
    
    
    }/****************************************************
      END 
     void print_Roman
    ******************************************************/
     
  2. macrumors 603

    Cromulent

    Joined:
    Oct 2, 2006
    Location:
    The Land of Hope and Glory
    #2
    Please use code tags when posting your code in future it backs it much easier to read.

    In simple terms passing arguments should just be a case of making sure the prototype is correct and then passing the said arguments. For example (in short hand code):

    Code:
    
    int randomFunction(int, int, int);
    
    int main()
    {
           int a, b, c;
    
           a = 1;
           b = 2;
           c = 3;
     
           randomFunction(a, b, c);
     
           return 0;
    }
     
    int randomFunction(int a, int b, int c)
    {
           int x;
           a + b + c = x;
    
           printf("%d", x);
    
           return 0;
     
    }
     
    
    Edit : After looking at your code, why are you passing memory references to the functions? Surely you should be passing the actual file handler or at least a pointer?
     
  3. thread starter macrumors newbie

    Joined:
    Mar 7, 2008
    Location:
    Michigan
    #3
    (I'll go back and fix the code. Sorry.)

    The assignment required passing one function's parameters to another function. We have learned to do that by using reference parameters. Pointers don't come up for another 200 pages or so.
     
  4. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #4
    I tried *hard* to grok what was going on here. It's admittedly been 8 years since I've seen C++.. but I think I have the general idea. I'm holding back on style criticism, as you didn't ask for a critique, but I will say the style could use some work (I'm not just talking about the indentation lost in the post).

    The code you posted would not compile, but I poked at it for a while and came up with this:

    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    char get_Data(ifstream& in_File, char& romanLet); /* gets Roman numbers, character by character, from input file*/
    
    void print_Roman(ofstream& out_File, char& romanLet); /* prints each Roman character to out_File as it's read into file*/
    
    int convert_Roman_to_Decimal(char,int);
    
    int isRoman(char);
    
    int main ()
    {
    
    // Declare variables
    
      char roman1 = ' '; 
      int deci = 0;
      int decimal1 = 0;
      int decimal2 = 0; 
      char o = ' ';
      int mathResult = 0;
    
      ifstream mp4romanletrdata;
      ofstream outRoman;
    
    // Open file
      mp4romanletrdata.open("./mp4romanletrdata");
      outRoman.open("outRoman"); 
    
    // Test opening
      if (!mp4romanletrdata || !outRoman)
      { 
        cout << "Unable to open files." << endl;
        cout << "Program terminates." << endl; 
      }
    
    
    
    {
      outRoman << "The first Roman Number is " ;
    
    // Calculate first number 
      do {
        roman1 = get_Data(mp4romanletrdata, roman1);
        if (isRoman(roman1)) {
          print_Roman(outRoman, roman1);
          decimal1 += convert_Roman_to_Decimal(roman1, deci);
        }
      } while (roman1 != ' ');
      outRoman << " ( " << decimal1 << " )." << endl;
    
      outRoman << "The second Roman Number is " ;
    }
    // there's more to the program, but this is the beginning of my trouble
    
    
    return 0;
    }
    /*****************************************************
    BEGIN 
    get_Data Function:
    *****************************************************/
    char get_Data(ifstream& in_File, char& romanLet)
    {
    
    char romanLetter; 
    
    
    // Get data char from input file
    
      if (in_File.get(romanLetter)) {
        cout << "Read the letter: " << romanLetter << endl;
        return romanLetter;
      } else {
        return ' ';
      }
    
    
    }/****************************************************
    END 
    get_Data
    ******************************************************/
    
    int convert_Roman_to_Decimal(char a,int b){
      return 1;
    }
    
    
    /*****************************************************
    BEGIN 
    void print_Roman:
    *****************************************************/
    
    void print_Roman(ofstream& out_File, char& romanLet)
    
    {
    
      out_File << romanLet; // decimal value totaled in main
    
    
    }/****************************************************
    END 
    void print_Roman
    ******************************************************/
    
    int isRoman(char testChar) {
      int retVal = 0;
      switch(testChar) {
        case 'I' :
        case 'V' :
        case 'X' :
        case 'L' :
        case 'C' :
        case 'D' :
        case 'M' : retVal = 1;
                   break;
        default: retVal = 0;
                      break;
      }
      cout << "Testchar is: " << testChar << "\t is? " << retVal << endl;
      return retVal;
    }
    The function calls seem fine. The other logic seemed a bit off. In print_Roman you passed in a char variable, then declared a similarly named variable, then printed that local thing instead of what was passed in. Also, a lot of variables were not initialized. I can't say i that was hurting or not, but it's better to be sure.

    You didn't leave your implementation of convert_Roman_to_Decimal, but I don't know how you would implement it the way you have things set up. I don't believe you can parse roman numerals one character at a time.

    In a previous thread you started, i posted this:
    http://forums.macrumors.com/showthread.php?p=5172983#post5172983

    If you keep track of things a bit differently it might be possible, but I really thing tokenizing is the right way to go about it.

    Of everything I saw the function calls actually seemed sound. It may have been some of the other logic that was muddling things up.

    -Lee

    Edit: I don't mean to sound harsh, I realize you are just starting out. I'd just like to promote good style from the start, and posting questions with usable code samples people can play with. People here like to help, but they'll be much more willing if you make it easier to concentrate on the functionality of the code, not getting something that will build. Also, at least when I was trying to get it to build my compiler choked on "char operator". Operator is a reserved word in C++, so I'd avoid it even if it makes the most sense.
     
  5. thread starter macrumors newbie

    Joined:
    Mar 7, 2008
    Location:
    Michigan
    #5
    This was the assignment: take an input file read an additive roman numeral in one character at a time, print it out one character at a time, translate it to a decimal one character at a time, do a math problem with it, translate the result to roman numerals and print it out. All done with functions. If the logic seems a bit off, it may because this particular problem drove me over the edge. And you can parse 'em one at a time, but it does hurt!


    Can you elaborate on what you mean by tonkenizing? Your usage doesn't sync with how my book uses the term. I don't mean to be obtuse, but I'm new!

    That's quite possible. I'm still not getting those references to pass in much simpler programs though.
     
  6. thread starter macrumors newbie

    Joined:
    Mar 7, 2008
    Location:
    Michigan
    #6
    No worries. You can't scare me.

    (I changed operator in the final version, I didn't save the changes tho' ... too much caffeine.)
     
  7. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #7
    Here's what I came up with. Not sure where the operator comes from, I just used +.

    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    char get_Data(ifstream& in_File, char& romanLet); /* gets Roman numbers, character by character, from input file*/
    
    void print_Roman(ofstream& out_File, char& romanLet); /* prints each Roman character to out_File as it's read into file*/
    
    int convert_Roman_to_Decimal(char&,int&);
    
    int isRoman(char&);
    
    string decimalToRoman(int&);
    
    int main ()
    {
    
    // Declare variables
    
      char roman1 = ' '; 
      int temp = 0;
      int deci = 0;
      int decimal1 = 0;
      int decimal2 = 0; 
      int result = 0;
      char o = ' ';
      int mathResult = 0;
    
      ifstream mp4romanletrdata;
      ofstream outRoman;
    
    // Open file
      mp4romanletrdata.open("./mp4romanletrdata");
      outRoman.open("outRoman"); 
    
    // Test opening
      if (!mp4romanletrdata || !outRoman)
      { 
        cout << "Unable to open files." << endl;
        cout << "Program terminates." << endl; 
      }
    
    
    
    {
      outRoman << "The first Roman Number is " ;
    
    // Calculate first number 
      decimal1=0;
      do {
        roman1 = get_Data(mp4romanletrdata, roman1);
        if (isRoman(roman1)) {
          print_Roman(outRoman, roman1);
          temp = convert_Roman_to_Decimal(roman1,deci);
          if(temp != -1) {
            decimal1 += convert_Roman_to_Decimal(roman1, deci);
          }
        }
      } while (roman1 != '\n');
      outRoman << " ( " << decimal1 << " )." << endl;
      decimal2=0;
      outRoman << endl << "The second Roman Number is ";
      do {
        roman1 = get_Data(mp4romanletrdata, roman1);
        if (isRoman(roman1)) {
          print_Roman(outRoman, roman1);
          temp = convert_Roman_to_Decimal(roman1,deci);
          if(temp != -1) {
            decimal2 += convert_Roman_to_Decimal(roman1, deci);
          }
        }
      } while (roman1 != '\n');
      outRoman << " ( " << decimal2 << " )." << endl;
      result=decimal1 + decimal2;
      outRoman << "The result of " << decimal1 << " + " << decimal2 
               << " = " << decimalToRoman(result) << endl;
    }
    // there's more to the program, but this is the beginning of my trouble
    
    
    return 0;
    }
    /*****************************************************
    BEGIN 
    get_Data Function:
    *****************************************************/
    char get_Data(ifstream& in_File, char& romanLet)
    {
    
    char romanLetter; 
    
    
    // Get data char from input file
    
      if (in_File.get(romanLetter)) {
        //cout << "Read the letter: " << romanLetter << endl;
        return romanLetter;
      } else {
        return ' ';
      }
    
    
    }/****************************************************
    END 
    get_Data
    ******************************************************/
    
    int convert_Roman_to_Decimal(char& a,int& b){
      int retVal = 0;
      switch(a) {
        case 'I' : retVal=1;
                   break;
        case 'V' : retVal=5;
                   break;
        case 'X' : retVal=10;
                   break;
        case 'L' : retVal=50;
                   break;
        case 'C' : retVal=100;
                   break;
        case 'D' : retVal=500;
                   break;
        case 'M' : retVal=1000;
                   break;
        default: retVal = -1;
                      break;
      }
      return retVal;
    }
    
    
    /*****************************************************
    BEGIN 
    void print_Roman:
    *****************************************************/
    
    void print_Roman(ofstream& out_File, char& romanLet)
    
    {
    
      out_File << romanLet; // decimal value totaled in main
    
    
    }/****************************************************
    END 
    void print_Roman
    ******************************************************/
    
    int isRoman(char& testChar) {
      int retVal = 0;
      switch(testChar) {
        case 'I' :
        case 'V' :
        case 'X' :
        case 'L' :
        case 'C' :
        case 'D' :
        case 'M' : retVal = 1;
                   break;
        default: retVal = 0;
                      break;
      }
      //cout << "Testchar is: " << testChar << "\t is? " << retVal << endl;
      return retVal;
    }
    
    
    string decimalToRoman(int& dec_num){
      string ret = "";
      int temp = dec_num; //Using a temp var b/c pass by ref. Don't want to change value
      while(temp > 0) {
        //cout << "Temp is: " << temp << " ret is: " << ret << endl;
        if(temp >= 1000) {
          ret.append("M");
          temp-=1000;
        } else if(temp >= 500) {
          ret.append("D");
          temp-=500;
        } else if(temp >= 100) {
          ret.append("C");
          temp-=100;
        } else if(temp >= 50) {
          ret.append("L");
          temp-=50;
        } else if(temp >= 10) {
          ret.append("X");
          temp-=10;
        } else if(temp >= 5) {
          ret.append("V");
          temp-=5;
        } else {
          ret.append("I");
          temp-=1;
        }
      }
      return ret;
    }
    Again, there are shortcuts on the roman numerals. If you pass in 4, you'll get IIII instead of IV, but it seems like that would suffice for this exercise. I don't know how different the rest of your code was from this, but the general calling mechanics seem to work.

    -Lee
     
  8. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #8
    Didn't expand on the tokenization in that last post. I meant to break the string into meaningful tokens. For example, if you have:
    MMCMCCCIVII

    The tokens are:
    M = 1000
    M = 1000
    CM = 900
    C = 100
    C = 100
    C = 100
    IV = 4
    I = 1
    I = 1

    in the case of roman numerals you have to break things up into the meaningful chunks that can be interpreted as a single decimal number. As you can see, the result would be much different if you treated each character atomically(as its own token). The maximum token length for roman numerals is 2, so that makes it a little easier.

    Generally when someone says tokenize they mean break apart a string into components. The *most* common case is breaking on a separator such as a tab, :, etc. In this case where the components are broken is less obvious.

    -Lee
     
  9. thread starter macrumors newbie

    Joined:
    Mar 7, 2008
    Location:
    Michigan
    #9
    Lee,

    I really didn't have any problems writing the individual functions, and they all worked fine independently. I didn't post them all here because the problem was getting my parameters to pass between them, and the first calls/functions are sufficient to illustrate that.

    Since there are still people who haven't turned in this assignment, I'm not interested in posting everything I wrote on the remote chance they'll feel free to plagiarize my sorry stuff. If what I've posted doesn't illuminate the problem, I'll have to wait for the prof to return it.

    Thanks for looking though...
     
  10. macrumors 65816

    Joined:
    Nov 26, 2007
    Location:
    Austin, TX
    #10
    So, chaos, I'm not sure you ever figured this out, so I thought I would share what I noticed. Basically, you are not assigning to nor using the values or references you are passing. I detailed it in the code snippets below:


    Code:
     
    /*****************************************************
     BEGIN 
     get_Data Function:
    *****************************************************/
    // So you are passing in a reference to romanLet here, but never 
    // assigigning to it.
    char get_Data(ifstream& in_File, char& romanLet)
    {
    
    char romanLetter; 
    
    	
    // Get data char from input file
    
    if (in_File.get(romanLetter))
    //      instead of the line below, returning the value
    //      assign it
    //	return romanLetter;	
            romanLet = romanLetter;  // now you are sending the value back to the caller
    // else return ' ';
    // same here
    else
      romanLet = ' ';
    
    // now return it
      return romanLet;
    
    }/****************************************************
      END 
      get_Data
    ******************************************************/
    
    
    
    /*****************************************************
     BEGIN 
     void print_Roman:
     *****************************************************/
    // Now in this function, there is no reason to pass by reference, so 
    //void print_Roman(ofstream& out_File, char& romanLet)
    void print_Roman(ofstream& out_File, char romanLet)
    
    {
    // You really don't have to create this romanLetter variable here,
    // but if you really want to, you need to set it to what you passed in
    // otherwise it just contains garbage.
    
    char romanLetter( romanLet ); // sent from get_Data
    
    out_File << romanLetter; // decimal value totaled in main
    
    
    }/****************************************************
      END 
     void print_Roman
    ******************************************************/
    Hope that helps.
     
  11. thread starter macrumors newbie

    Joined:
    Mar 7, 2008
    Location:
    Michigan
    #11
    Scooby, thanks for looking.

    When I've tried it that way, I get this: "error: declaration of 'std::string name;' shadows a parameter" and it won't compile. It does compile the way I've got it, but the results are junk.
     
  12. macrumors newbie

    Joined:
    Mar 26, 2008
    #12
    Hey, I'm having a problem with XCode when opening input documents..
    Where is the root folder for them? I mean.. in MS Windows the instruction infile.open("test.txt"); would be ok if you had the test.txt file within the project folder, but in XCode that doesn't happen.. i'm only able to open that file if I explicit all the path to the file: "/users/.../test.txt" :S

    chaos is your .open function working properly? this is because you have outRoman.open("outRoman"); just like me, except for the .txt suffix..

    P.S: I'm using XCode 3.0 btw.
     
  13. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #13
    See this thread, it is applicable to your issue:
    http://forums.macrumors.com/showthread.php?t=460868
     
  14. macrumors newbie

    Joined:
    Mar 26, 2008
    #14
    lee1210 i had already read that i guess.. but it didn't resolve anything.

    Fortunatly, shortly after I posted I found the answer in another thread..
    http://forums.macosxhints.com/archive/index.php/t-35892.html

    As for me, my program was running under the user root directory.. :\

    Sorry to change the subject of the post. Thanks anyways ;)
     
  15. macrumors 65816

    Joined:
    Nov 26, 2007
    Location:
    Austin, TX
    #15
    That error is unrelated and is because of some other error in your program. The errors in your program I pointed out are indeed errors and the recommendations are correct - but take them or leave them.
     

Share This Page