Solved

newbie: passing strings from one function to another.

Posted on 2004-10-07
7
308 Views
Last Modified: 2010-04-24
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
Comment
Question by:daniel416
  • 3
  • 2
7 Comments
 
LVL 19

Expert Comment

by:drichards
ID: 12251229
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
 
LVL 6

Expert Comment

by:Svetlin_Panayotov
ID: 12256152
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
 
LVL 3

Author Comment

by:daniel416
ID: 12256664
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
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 3

Author Comment

by:daniel416
ID: 12256714
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
 
LVL 19

Accepted Solution

by:
drichards earned 125 total points
ID: 12257170
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
 
LVL 3

Author Comment

by:daniel416
ID: 12260826
@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

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

The following diagram presents a diamond class hierarchy: As depicted, diamond inheritance denotes when two classes (e.g., CDerived1 and CDerived2), separately extending a common base class (e.g., CBase), are sub classed simultaneously by a fourt…
In Easy String Encryption Using CryptoAPI in C++ (http://www.experts-exchange.com/viewArticle.jsp?aid=1193) I described how to encrypt text and recommended that the encrypted text be stored as a series of hexadecimal digits -- because cyphertext may…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now