• Home
  • Reviews
  • Articles
  • News
  • Tools
  • GamingHeaven
  • Forums
  • Network
 

Go Back   DriverHeaven.net > Forums > Software / Tools > Programming, Coding, (Web)Design

Notices

Reply
 
LinkBack Thread Tools
Old Apr 11, 2005, 01:35 PM   #1
DriverHeaven Addict
 
Join Date: Jun 2002
Posts: 315
blix9 is on a distinguished road

cstring in C++

I hope this is a right place to ask something like this.
What is with this c-string thing? I know they are basically a pointer to the first elements of the char array. I thought I wrote everything correct regarding the rules of the null-terminated char arrays in my last homework. However, when I pass them around in some 'getName()' and 'printName()' member functions in a class and try to output in a main function they get kinda all mangled up and display garbage with partially correct outputs in the begining part of the names... such as...

Julliane M%$@&* // Julliane Moore
Tom @#^ //Tom Cruise



The thing is, to print a name, I have to pass a char* around as a paprameter in some helper functions in the class which are not visible to clients. I just am required to do this way. Later, also, I have to use the same helper function(display) for non-member variable which is passed on by a member functions.

class personalInfo
{
personalInfo(char* name, int age ......);
....
....
char* getName() const;
....
};


void display(char*); // helper function prototype in class.cpp file

void printName() const // in class.cpp file
{ display( getName() ); }

// in test code it looks like

aClass.printName(); //in testClass.cpp file

Can you think of what's causing this? I think am doing something stupid with this. Maybe it is not a c-string problem? I am clueless.
Any help would be appreciated. BTW, I am using gcc compiler in a school server, not MS Visual C++. It has to work in school machines.
If anyone is interested I can present the code for the class and test file here.

thanks...

Last edited by blix9; Apr 11, 2005 at 04:36 PM.
blix9 is offline   Reply With Quote
Old Apr 12, 2005, 12:56 PM   #2
Delete Me
 
Join Date: Mar 2004
Posts: 14,676
pr0digal jenius is a name known to allpr0digal jenius is a name known to allpr0digal jenius is a name known to allpr0digal jenius is a name known to allpr0digal jenius is a name known to allpr0digal jenius is a name known to all

Can you post a bit more of the code, especially how it's being inputted
pr0digal jenius is offline   Reply With Quote
Old Apr 12, 2005, 03:57 PM   #3
DriverHeaven Addict
 
Join Date: Jun 2002
Posts: 315
blix9 is on a distinguished road

It is input when the object is created which is a class 'personalInfo'.

personalInfo person1("Tom Cruise", 35, etc...)

the constructor and other functions look like...

personalInfo:: personalInfo(char* nm, int age, etc...)
{
strcpy(name, nm);
year=age;

.....
}


char* passenger:: getName() const
{
char ans[20]; ans[0]='\0';
return strcpy(ans, name);
}


void passenger:: printName() const
{
display(getName());
}


void display(const char* word)
{
for ( int i=0; word[i]!='\0'; i++)
cout << word[i];
}


private members of the class are
char name[20];
int year;
....


Thanks for any help man.
blix9 is offline   Reply With Quote
Old Apr 12, 2005, 10:23 PM   #4
Delete Me
 
Join Date: Mar 2004
Posts: 14,676
pr0digal jenius is a name known to allpr0digal jenius is a name known to allpr0digal jenius is a name known to allpr0digal jenius is a name known to allpr0digal jenius is a name known to allpr0digal jenius is a name known to all

i'm assuming you did all the proper #include code at the top, firstly.

secondly,

char* passenger:: getName() const
{
char ans[20]; ans[0]='\0';
return strcpy(ans, name);
}

that part evades me as to exactly how it works (I do Java, and the char ans[20]; ans[0]='\0'; part evades my minimal knowledge of C++)...what does that part do? are you concatenating the char's into a string, or what?
pr0digal jenius is offline   Reply With Quote
Old Apr 13, 2005, 04:00 AM   #5
DriverHeaven Addict
 
Join Date: Jun 2002
Posts: 315
blix9 is on a distinguished road

yes I did #include <cstring> and #include <cctype>. they are ususally included together.

Ok in java, there's generally a string object. but in C++ there's this c-type string(hence called cstring) which is inherited from old C besides the STL's 'string' class(which is like enhanced version of cstring for C++). They work little differently. The null-terminated cahracter array is the c-string and it ends with '\0'. By doing this...
char ans[20]; ans[0]='\0';
I created an empty null-terminated character with the size enough to hold as many as 19 characters later. The last space is for the '\0' So if I create a cstring of five characters, say, "Darth" index 4 is 'h' and index 5 is '\0' and the rest is garbage.
'strcpy' function is for the cstring type which copies the second argument to the first argument and add '\0' at the end automatically and returns a pointer(char*) to the first element of the array. Both arguments have to be cstring type(null terminated characters) and the first argument has to be large enough to copy the second argument.
For concatenation, there is another cstring function called 'strcat'
I know it's nicer to hadle strings in Java but an relatively older language like C++ with its root in even older C it gets rather messy. I just can't figure out my code vomits those garbages when it's not supposed to.

Last edited by blix9; Apr 13, 2005 at 04:06 AM.
blix9 is offline   Reply With Quote
Old Apr 13, 2005, 10:14 AM   #6
Delete Me
 
Join Date: Mar 2004
Posts: 14,676
pr0digal jenius is a name known to allpr0digal jenius is a name known to allpr0digal jenius is a name known to allpr0digal jenius is a name known to allpr0digal jenius is a name known to allpr0digal jenius is a name known to all

OK, just out of curiosity, run it as is with no spaces in the names, like: TomCruise and see if it vomits.

If not, your delimiter is messing up and you're going to have to manually set it, or run the name as 2 arrays and break off the 1st one at the space, or something.
pr0digal jenius is offline   Reply With Quote
Old Apr 23, 2005, 08:49 PM   #7
DriverHeaven Junior Member
 
Join Date: Mar 2005
Posts: 21
cjohnsto is on a distinguished road

Here is some of the code you pasted with fixes and cooments throughout it. I have not tested or compiled it so it may require some tweaking to get going. Also please do not just copy and paste what I have given you into your assignmemt try and understand what was causing the problem. (returning a pointer that was no longer valid.)
Sorry if I am preachy but I have taught C++ for a few years and habits die hard.


personalInfo:: personalInfo(char* nm, int age, etc...)
{
strcpy(name, nm);
year=age;

.....
}


//char* passenger:: getName() const
//If you want it so they cant do bad stuff to your internal state then make the //return type const char* infact I recomend it.
const char* passenger:: getName() const
{
//this is what is causing the bad printout. ans is not valid once this function
// returns so you would be passing back a bad pointer
//char ans[20]; ans[0]='\0'; //EDIT also for future reference char ans[20] = ""; would be easier to understand and do the same thing.
//return strcpy(ans, name);
return name; //if they want to copy it let them.
}


void passenger:: printName() const
{
display(getName());
}


//void display(const char* word)
void display(const char* word) const
{
//for ( int i=0; word[i]!='\0'; i++)
//cout << word[i];
cout << word; //keep it simple, this will work fine
}


private members of the class are
char name[20]; //this will make the max name 19 characters long
//perhaps this is already specified but it would be best to peroperly allocate
// space in the constructor and free it in the deconstructor (however this is not strictly necessary just good programming)
int year;
....
cjohnsto is offline   Reply With Quote
Old Apr 29, 2005, 12:39 AM   #8
DriverHeaven Newbie
 
Join Date: Feb 2005
Posts: 14
logos1 is on a distinguished road

Code:
personalInfo::personalInfo(char* nm, int age, etc...)
  { name = new char [sizeof (nm)]; strcpy (name, nm); year = age; }
personalInfo::personalInfo (const personalInfo& x)
  { name = new char [sizeof (x.name)]; strcpy (name, x.name); year = x.year; }
~personalInfo::personalInfo ()
  { delete [] name; name = 0; }
const char* passenger::getName () const
  { return name; }
..simplify
logos1 is offline   Reply With Quote
Old Apr 29, 2005, 08:52 AM   #9
DriverHeaven Junior Member
 
Join Date: Mar 2005
Posts: 21
cjohnsto is on a distinguished road

Quote:
Originally Posted by logos1
Code:
personalInfo::personalInfo(char* nm, int age, etc...)
  { name = new char [sizeof (nm)]; strcpy (name, nm); year = age; }
personalInfo::personalInfo (const personalInfo& x)
  { name = new char [sizeof (x.name)]; strcpy (name, x.name); year = x.year; }
~personalInfo::personalInfo ()
  { delete [] name; name = 0; }
const char* passenger::getName () const
  { return name; }
..simplify
This is bugged. You need to allocate sizeof + 1. The extra 1 is for the null terminator. It is a very common mistake.
cjohnsto is offline   Reply With Quote
Old Apr 29, 2005, 10:29 AM   #10
DriverHeaven Newbie
 
Join Date: Feb 2005
Posts: 14
logos1 is on a distinguished road

yea.. it is, but not for that reason. the sizeof operator returns the number of bytes/units allocated for a specific variable.. a null-terminated string with a total of n characters has no more than n-1 available indices, so setting n+1 has you attempting to step over the bounds.
sizeof doesn't like dynamically allocated memory, so to get the size.. either implement your own function (you'd have to.. if there's a size limitation) or use strlen().
logos1 is offline   Reply With Quote
Old Apr 29, 2005, 10:22 PM   #11
DriverHeaven Junior Member
 
Join Date: Mar 2005
Posts: 21
cjohnsto is on a distinguished road

I read sizeof thought strlen
cjohnsto is offline   Reply With Quote
Old May 1, 2005, 08:15 PM   #12
DriverHeaven Addict
 
Join Date: Jun 2002
Posts: 315
blix9 is on a distinguished road

oh, thanks folks for all the great help. I am having other few new assignments I had to take care of. They come in waves as you might already know it.
I have already long missed this assignment for grading but I still wanna see it working flawlessly. I'll look into your suggestions in this thread as soon as I get other things turned in.

BTW, can't use dynamic arrays here. Yup, our instructor told us so. Why? Beats me. She likes to shove bugs up our asses for the sake of learning I guess.

Again thank you for the input. It really helps.

Last edited by blix9; May 1, 2005 at 08:40 PM.
blix9 is offline   Reply With Quote
Old May 1, 2005, 10:39 PM   #13
DriverHeaven Newbie
 
Join Date: Feb 2005
Posts: 14
logos1 is on a distinguished road

well, if the size of the arrays are static.. then you'll need to use strncpy instead.

simple solution.. make a public static const member for personalInfo called SIZE and set it equal to the max size of the name.
then after the #include statements in the source file, type..
#ifdef strcpy
#undef strcpy
#define strcpy(s,d) strncpy(s,d,SIZE)

and at the end..
#undef strcpy
logos1 is offline   Reply With Quote
 

 
Powered by: vBulletin
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0
Artwork by Allan 'Zardon' Campbell, vBulletin implementation by Craig '5320' Humphreys based on original artwork by Ratchet.

All times are GMT -5. The time now is 11:19 AM. Copyright ©2008 HeavenMedia.net