String appending

This is a discussion on String appending within the C++ Programming forums, part of the General Programming Boards category; How to easily append a string to another, which is dynamically allocated? strcat function is strangeful. Three times it appends ...

  1. #1
    Registered User larry's Avatar
    Join Date
    Sep 2001
    Posts
    96

    String appending

    How to easily append a string to another, which is dynamically allocated? strcat function is strangeful. Three times it appends strings well and the fourth time it does some crap.

    Here is an example of code:
    Code:
    char* allocate(char* input) {
      int size = sizeof(vstup);
      char *output = new char[size];
      memcpy(output, input, size);  //or strcopy, doesn't matter
      return output;
    }
    
    char* formattedstring(char* string1, char* string2) {
      const char lbracket[2] = "(", divider[2] = ",", rbracket[2] = ")";
      char thestring[] = "";
      strcat(thestring, lbracket);
      strcat(thestring, string1);
      strcat(thestring, divider);
      strcat(thestring, string2);
      strcat(thestring, rbracket);
      /*I need to use this allocate function calling because I want to
        allocate thestring dynamically and because thestring variable
        is destroyed after this function (formatted string) finishes*/
      return allocate(thestring);
    }
    
    int main() {
      cout << formattedstring("1st", "2nd");
      return 0;
    }
    I know I should free up the memory after allocating it with "new". But I don't know how as I don't know how many times I will call the allocate function.
    But it doesn't matter for me now. My question is how to append those 5 strings if the strcat function can't do the job?
    Please excuse my poor english...

  2. #2
    Registered User larry's Avatar
    Join Date
    Sep 2001
    Posts
    96
    Maybe my problem is overlapping or something...

    I wish I could use old Pascal-style thestring = "(" + "1st" + "," + "2nd" + ")";
    Please excuse my poor english...

  3. #3
    zen
    zen is offline
    of Zen Hall zen's Avatar
    Join Date
    Aug 2001
    Posts
    1,007
    A couple of points -

    1)In your formattedstring() function the string needs enough memory allocated to hold the string that will be placed into it. It should be -

    char thestring[10] = "";

    2) When arrays are passed into functions they are passed by their address. There isn't a way to pass the sizeof the array unless you pass the size in as a seperate parameter. So when you do -

    int size = sizeof(input);

    you are taking the sizeof a pointer not the sizeof the array so insufficient memory will be allocated. If you want the length of the string you can use strlen(); and add one for the terminating NULL.
    zen

  4. #4
    Registered User larry's Avatar
    Join Date
    Sep 2001
    Posts
    96
    I forgot to translate - vstup means input so the line should look like this: "int size = sizeof(input);"

    > If you want the length of the string you can use strlen(); and add one for the terminating NULL.
    I was using this method before and from unknown reason, I began using sizeof()...OK, I'm going back to strlen()

    >It should be - char thestring[10] = "";
    That's it. I thought strcat function allocates enough memory after first item in thestring array and puts characters from source string there. It does not do it? Actually, I don't want to write some const value as a size of thestring array. My goal is to allocate only memory needed and not more. For example, if string1 and string2 should be 300 bytes long, I need thestring to have 298 (without terminators) + 1 + 1 + 1 (brackets, divider and terminator) bytes. And if string1 and string2 should be 2 bytes each, I need thestring to have 2 + 1 + 1 + 1 bytes. Do you catch my "strange" English? If so, is there any way to do what I need?
    Please excuse my poor english...

  5. #5
    zen
    zen is offline
    of Zen Hall zen's Avatar
    Join Date
    Aug 2001
    Posts
    1,007
    If you want to extend the string dynamically then you'll have to do something like the following:

    1) Get length of string before it's been appended.

    2) Get length of string to be added.

    3) Allocate enough memory to hold the total of these two values (plus the NULL).

    4) Copy first string into newly allocated memory (strcpy()).

    5) If initial string was dynamically allocated, and you no longer need it, then delete the storage for it.

    6) Append the string in the newly allocated memory with the extra characters (using strcat()).

    However, if don't want to have to handle this yourself you can use the C++ string class that will do the memory allocation(and deallocation) for you. It also allows you to use the = operator to copy strings and the + operator to append a string.
    zen

  6. #6
    Registered User larry's Avatar
    Join Date
    Sep 2001
    Posts
    96
    I know this. I plan to use string library functions in future, but I'd like to know how does it work, how to handle strings by myself. I've found out that I don't even know how to properly allocate memory. Even if I use new or alloc, it doesn't allocate the amount of bytes I need. For example this:
    Code:
    void allocate() {
      char *pstr = new char[3];
      cout <<"pstr=='"<<"' strlen(pstr)=="<<strlen(pstr)<<endl;
      delete [] pstr;
    }
    
    int main() {
      allocate();
      return 0;
    }
    results to:
    Code:
    pstr=='---רררר' strlen(pstr)==7
    Press any key to continue
    So "new" allocates 7 bytes instead of 3.
    Can you explain me why?
    Please excuse my poor english...

  7. #7
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,484
    > Even if I use new or alloc, it doesn't allocate the amount of bytes I need.
    No - new char[3] tells you that you have 3 bytes.

    strlen(pstr) simply looks through the (uninitialised) memory looking for a \0 byte. It has no knowledge of where the memory came from (local array, global array, allocated memory). Since it's uninitialised, there's no telling where (or even if) it will find a \0.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  8. #8
    Registered User larry's Avatar
    Join Date
    Sep 2001
    Posts
    96
    I understand.
    I customized my allocate function like this and it works fine:
    Code:
    void allocate() {
      char *pstr = new char[3];
      pstr[0] = '1';
      pstr[1] = '2';
      pstr[2] = '\0';
      cout <<"pstr=='"<<pstr<<"' strlen(pstr)=="<<strlen(pstr)<<endl;
      delete [] pstr;
    }
    But this doesn't work fine, it generates an error when running:
    Code:
    void allocate() {
      char *pstr = new char[3];
      pstr = "12";
      cout <<"pstr=='"<<pstr<<"' strlen(pstr)=="<<strlen(pstr)<<endl;
      delete [] pstr;
    }
    If I assign a "12" value to a pointer, it fills the memory that pointer points to, doesn't it? Or it makes pointer to point somewhere else? If so, how could I assign "12" string to memory allocated with new through pstr pointer?
    Please excuse my poor english...

  9. #9
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,484
    > If I assign a "12" value to a pointer, it fills the memory that pointer points to, doesn't it?
    No, it replaces the pointer value with another pointer value ("" strings exist as char* pointers as far as the compiler is concerned).

    &nbsp; pstr = "12";
    So you forget the pointer returned by new, and replace it with another pointer value (which happens to point to the start of a string containing "12").
    Since this pointer wasn't returned by new, it's invalid to try and delete it.

    If you want to copy the string, its
    &nbsp; strcpy( ptr, "12" );
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  10. #10
    Registered User larry's Avatar
    Join Date
    Sep 2001
    Posts
    96

    Smile

    Thanx, I'm getting into this slowly. I was using Pascal before and I'm confused by C++ string memory allocations and stuff...
    Please excuse my poor english...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Please check my C++
    By csonx_p in forum C++ Programming
    Replies: 263
    Last Post: 07-24-2008, 09:20 AM
  2. String Class
    By BKurosawa in forum C++ Programming
    Replies: 117
    Last Post: 08-09-2007, 01:02 AM
  3. Program using classes - keeps crashing
    By webren in forum C++ Programming
    Replies: 4
    Last Post: 09-16-2005, 03:58 PM
  4. problems with overloaded '+' again
    By Brain Cell in forum C++ Programming
    Replies: 9
    Last Post: 04-14-2005, 05:13 PM
  5. Again Character Count, Word Count and String Search
    By client in forum C Programming
    Replies: 2
    Last Post: 05-09-2002, 11:40 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21