• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 322
  • Last Modified:

newbie: passing strings from one function to another.

hello,
i'm trying to get user input, keeping the presentation separate from the logic as much as possible.
i have a problem passing strings correctly (i get garbage).
in my main function i have:
int _tman(){
    Display display // class taking care of displaying stuff on the screen
    char * FN[31]; // first name
...
    *FN = (display.enterFN(30));
...
}

//and here is my enterFN function
char * Display::enterFN(int pMax) {
// enter first name
char locFN[31];
int status = 0;
      do {
            cout << "First Name" << endl;
            cin >> locFN;
            if (strlen(locFN) <= pMax) {
                  status = 0;
            }
            else {
                  cout <<"Max 30 characters" << endl;
                  status = 1;
                  }
            }
      while (status == 1);
return locFN;
}

FN is then filled with garbage.
maybe someone can "point" me in the right direction.
much appreciate all the help.
daniel.
0
daniel416
Asked:
daniel416
  • 3
  • 2
1 Solution
 
drichardsCommented:
locFN is a local variable and goes out of scope when the function returns, so FN is left pointing to stack memory that is now being used for other purposes.  Also, FN should be 'char *FN;'.  There are a couple of ways to fix it:

1) Copy the returned string before it goes away:

   char FN[31]; // Note no *
   strcpy(FN, display.enterFN(30));

2) Allocate locFN on the heap - you'll need to delete it later:
in main:

    char *FN = display.EnterFN(30);

Then when you're done with FN:

    delete[] FN;

in enterFN:

    char *locFN = new char[31];

3) Use std::string - like (1) but std::string is smart about copying strings:
in main:

    std::string FN = display.enterFN(30);

in enterFN:

    std::string locFN;
    do {
          cout << "First Name" << endl;
          std::getline(cin,locFN);
          if (locFN.length() <= pMax) {
               status = 0;
          }
          else {
               cout <<"Max 30 characters" << endl;
               status = 1;
               }
          }
     while (status == 1);
return locFN;
0
 
Svetlin_PanayotovCommented:
Yet another - change Display::enterFN(int pMax) to
void Display::enterFN(char* sName, int pMax)

void Display::enterFN(char* sName, int pMax)
{
      int status = 0;
      do {
            cout << "First Name" << endl;
            cin >> sName;
            if (strlen(sName) <= pMax) {
                  status = 0;
            }
            else {
                  cout <<"Max 30 characters" << endl;
                  status = 1;
            }
      }
      while (status == 1);
return;
}

There are countless variations :)
Svetlin
0
 
daniel416Author Commented:
hmm...
(*scratch scratch*)
this is what i got working...(a combination of drichards' options 1 and 2)

int _tman(){
    char FN[31]; // first name string // no *
...
    *FN = display.enterFN(30); // assign content of FN to return value of enter.FN()
...
}
//enterFN()...
char Display::enterFN(int pMax) { // no *
char locFN; // not locFN[31]
int status = 0;
     do {
          cout << "First Name" << endl;
          cin >> locFN;
          if (strlen(&locFN) <= pMax) { // strlen takes address of locFN
               status = 0;
          }
          else {
               cout <<"Max 30 characters" << endl;
               status = 1;
               }
          }
     while (status == 1);
return locFN;
}

 -----
i was trying to keep things on the stack as much as possible. strcpy worked, but i could only get it to work when i allocated a string on the heap and passed a pointer as parameter 2.

@svetlin
thanks for proposing an aswer .... i need to investigate it. it's not entirely clear to me how enterFN() can assign something other than the local sName. wouldn't it go out of scope after exiting?
or because sName is also a parameter, is it passed back to the calling environment, regardless of the void in the implementation?

thanks again for your help!
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

 
daniel416Author Commented:
whooops!
while accepting the answer, i meant to add 20 points and award them to svetlin for contributing. instead,
i awarded all the points to drichards.
do you mind if we fix this?
0
 
drichardsCommented:
If your new enterFN above is accurate, you should NOT use it.  I don't understand how it would work at all since it would only return one character.  As I think about it more critically, you should use (3) from my original post.  (1), (2), and Svetlin's solutions all have a major problem which is that they have a potential buffer overrun problem.  There is no way to prevent the user from entering a really long string which will overflow the character buffer you have allocated for the name.  If this happens, you overwrite the program stack which causes all sorts of difficulties up to and including crashing your program.

(3) manages allocating a large enough string for you so a buffer overrun does not happen.
0
 
daniel416Author Commented:
@drichards.
i am humbled.
in a tired and emotional state, i was testing my function with only one character!
how foolish.
thanks for your help.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now