cstring in C++

Discussion in 'General Software Discussion' started by blix9, Apr 11, 2005.

  1. blix9

    blix9 New Member

    Joined:
    Jun 9, 2002
    Messages:
    315
    Likes Received:
    0
    Trophy Points:
    0
    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

    :confused:

    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: Apr 11, 2005
  2. pr0digal jenius

    pr0digal jenius Delete Me

    Joined:
    Mar 15, 2004
    Messages:
    14,526
    Likes Received:
    28
    Trophy Points:
    0
    Can you post a bit more of the code, especially how it's being inputted
     
  3. blix9

    blix9 New Member

    Joined:
    Jun 9, 2002
    Messages:
    315
    Likes Received:
    0
    Trophy Points:
    0
    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!='\0'; i++)
    cout << word;
    }


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


    Thanks for any help man.
     
  4. pr0digal jenius

    pr0digal jenius Delete Me

    Joined:
    Mar 15, 2004
    Messages:
    14,526
    Likes Received:
    28
    Trophy Points:
    0
    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?
     
  5. blix9

    blix9 New Member

    Joined:
    Jun 9, 2002
    Messages:
    315
    Likes Received:
    0
    Trophy Points:
    0
    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: Apr 13, 2005
  6. pr0digal jenius

    pr0digal jenius Delete Me

    Joined:
    Mar 15, 2004
    Messages:
    14,526
    Likes Received:
    28
    Trophy Points:
    0
    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.
     
  7. cjohnsto

    cjohnsto New Member

    Joined:
    Mar 4, 2005
    Messages:
    21
    Likes Received:
    0
    Trophy Points:
    0
    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!='\0'; i++)
    //cout << word;
    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;
    ....
     
  8. logos1

    logos1 New Member

    Joined:
    Feb 8, 2005
    Messages:
    14
    Likes Received:
    0
    Trophy Points:
    0
    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
     
  9. cjohnsto

    cjohnsto New Member

    Joined:
    Mar 4, 2005
    Messages:
    21
    Likes Received:
    0
    Trophy Points:
    0
    This is bugged. You need to allocate sizeof + 1. The extra 1 is for the null terminator. It is a very common mistake.
     
  10. logos1

    logos1 New Member

    Joined:
    Feb 8, 2005
    Messages:
    14
    Likes Received:
    0
    Trophy Points:
    0
    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().
     
  11. cjohnsto

    cjohnsto New Member

    Joined:
    Mar 4, 2005
    Messages:
    21
    Likes Received:
    0
    Trophy Points:
    0
    I read sizeof thought strlen :(
     
  12. blix9

    blix9 New Member

    Joined:
    Jun 9, 2002
    Messages:
    315
    Likes Received:
    0
    Trophy Points:
    0
    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.:wtf: Why? Beats me. She likes to shove bugs up our asses for the sake of learning I guess.:D

    Again thank you for the input. It really helps.:)
     
    Last edited: May 2, 2005
  13. logos1

    logos1 New Member

    Joined:
    Feb 8, 2005
    Messages:
    14
    Likes Received:
    0
    Trophy Points:
    0
    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
     

Share This Page

visited