简体   繁体   中英

Implementing an insert in a custom string class in C++?

I am implementing my own MyString class in cpp. I have successfully completed the functions for length, isEmpty, find, compare, clear, insert, and have overloaded the << and == operators. The only function I am having trouble completing is the insert function. The description for insert is "extends the current string content by inserting some additional content (str or s) at a specific location (pos) within the string content. Existing content is shifted to the right. It returns 0 upon successful execution of the function. Otherwise, it returns -1." The following is the function I have now, which builds and runs with no errors, but has incorrect logic:

// inserts some additional content str at a specific location pos within the string content
int MyString::insert(int pos, const MyString& str) {

if (pos < 0 || pos > size) // out of bounds
    return -1;
for (int i = pos; i < pos + str.length(); i++) // shift existing content to right
    content[i+str.length()] = content[i];
for (int i = pos; i < pos + str.length(); i++) // insert new content
    content[i] = str.content[i-pos];
return 0;

}

content is the string that I am inserting str into. I am testing it with the following code:

MyString ms12 = "This string will test the function";
MyString testInsert = "insert ";
ms12.insert(26, testInsert);

This test will result in content being the string "This string will test the insert function" once insert is successfully completed. When I run the code right now and print out m12, the output I get is "This string will test the insert functio════════════════════════════════════════²²²²½½½½½½½½ε■ε■". So it is inserting the new data str ("insert ") into the string, but it is not correctly shifting the previous content to the right. My char* array that I am using to implement the string is set at size 80, so I have plenty of room to insert this.

I know it must be the logic of the first for loop, but I have no idea how to fix it. Thanks for any help.

I think you have several possible flaws in your code.

  1. The first if test could be flawed since you did not take into account the length of str which could be a large string and make size not big enough

  2. when you shift your contnet you need to mark the end of the string with \\0 .

  3. the shift algorithm is not quite right as pointed out by molbdnilo, you need to shift all the chars after pos . Then you need to shift from the last char back to pos , othewise you will overwrite some chars.

I think you should check that insert is not overflowing content and content is zero-filled. Also, you may simplify the routine a bit, check the snippet below:

int MyString::insert(size_t pos, const string& str){
    if ((pos + str.size()) >=  size)
        return -1;
    memmove(content + pos + str.size(), content + pos , strlen(content));
    memcpy(content + pos, str.c_str(), str.size());
    return 0;
}

Two things to be aware of:

  1. You need to allocate a new array, as the size of content has extended after insertion.
  2. When shifting content, copy backwards to avoid old content being overwritten.

eg

int MyString::insert(int pos, const MyString& str) {
  if (pos < 0 || pos > size) // out of bounds
      return -1;
  int newlen = size+str.length()+1;
  char tmp[newlen];
  strcpy(tmp, content);
  for (int i = newlen-1; i>pos; i--) // shift existing content to right
      tmp[i] = tmp[i-str.length()];  // copy backwards
  for (int i = pos; i < pos + str.length(); i++) // insert new content
      tmp[i] = str.content[i-pos];
  delete content; content = new char[newlen];  // allocate a new array
  strcpy(content, tmp);
  return 0;
}

Another idea is to use std::string for member content , will make this method more concise and easy to understand.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM