Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

chaos2828

macrumors newbie
Original poster
Mar 7, 2008
10
0
Michigan
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
******************************************************/
 

Cromulent

macrumors 604
Oct 2, 2006
6,812
1,100
The Land of Hope and Glory
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?
 

chaos2828

macrumors newbie
Original poster
Mar 7, 2008
10
0
Michigan
(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.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
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:
https://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.
 

chaos2828

macrumors newbie
Original poster
Mar 7, 2008
10
0
Michigan
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.

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!

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

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

chaos2828

macrumors newbie
Original poster
Mar 7, 2008
10
0
Michigan
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.

No worries. You can't scare me.

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

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
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
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
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
 

chaos2828

macrumors newbie
Original poster
Mar 7, 2008
10
0
Michigan
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...
 

ScoobyMcDoo

macrumors 65816
Nov 26, 2007
1,188
37
Austin, TX
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.
 

chaos2828

macrumors newbie
Original poster
Mar 7, 2008
10
0
Michigan
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.
 

sh0ck3r

macrumors newbie
Mar 26, 2008
2
0
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.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
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.

See this thread, it is applicable to your issue:
https://forums.macrumors.com/threads/460868/
 

ScoobyMcDoo

macrumors 65816
Nov 26, 2007
1,188
37
Austin, TX
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.

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.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.