0

I need to shift all elements at a particular index to the right in a dynamically allocated char ** so that I can insert a string in the array.

I am confused about how I can transverse through the string stored at a particular index so that I can move them to the right?

The function receives and int index, a pointer to struct SmartArray, and a char *str string that is to be inserted at said index.

Am I on the right track? Is this there a more efficient way to do this?

This is what I've come up with so far:

char *insertElement(SmartArray *smarty, int index, char *str)
{
  int i;
  char temp;

  // Any elements to the right of index are shifted one space to the right., not sure if this is correct way to find strlen
  for (i = index; i < strlen(smarty->array[index]); i++)
  {
    temp = smarty->array[index]
    if (i == index)
    {
      smarty->array[index] = str[i];
    }
   else
   {
     smarty->array[index] = temp;
   }

  }

}

This is the struct I am working with:

    typedef struct SmartArray
{
    // We will store an array of strings (i.e., an array of char arrays)
    char **array;

    // Size of array (i.e., number of elements that have been added to the array)
    int size;

    // Length of the array (i.e., the array's current maximum capacity)
    int capacity;

} SmartArray;
starlight
  • 130
  • 1
  • 18
  • 1
    This is a good use-case for [`memmove`](http://en.cppreference.com/w/c/string/byte/memmove). – Some programmer dude Feb 13 '17 at 00:09
  • Please provide a [mcve]. We need to see exactly how all types are defined, how memory was allocated, etc. – kaylum Feb 13 '17 at 00:10
  • Oh and you have a really bad logical error in the code you show, something which a good compiler will warn you about. – Some programmer dude Feb 13 '17 at 00:19
  • @kaylum is this better? – starlight Feb 13 '17 at 00:20
  • @Some Programmer dude it compiles just fine for me... – starlight Feb 13 '17 at 00:21
  • But it doesn't work when you run it? Perhaps because you use *assignment* instead of comparing for equality. Something you would have found out *very* quickly if you just took a few minutes to step through the code in a debugger. Then there's the problem with the loop condition, are you sure you want to loop over the *string length* and not the array length? Also easily found with a quick step-through in a debugger. – Some programmer dude Feb 13 '17 at 00:22
  • @Some programmer dude I want to loop through the pointer that Smarty->array is pointing to, which is a pointer to a pointer that points to a string. This is why I'm confused. I don't quite understand how to transverse through the pointer that points to the string. – starlight Feb 13 '17 at 00:29
  • See my first comment: You don't *have* to loop anything at all. All you need is a single calls to `memmove`. But since you're a beginner (it seems) doing this *once* is a good exercise, but then you need to stop and think a little: You have an array of pointer, right? That means you need to "move" *the pointers* and you should loop over the elements in the array (i.e. `smarty->size` in your case). And of course learn the difference between comparison for equality `==` and assignment `=`. – Some programmer dude Feb 13 '17 at 00:33
  • @Some programmer dude The assignment operator was a typo I overlooked. As for the memmove, that looks like it'd work. However, before I take the 'easy way out' I do want to learn how to code something like this in a loop so I understand it better. – starlight Feb 13 '17 at 00:39

1 Answers1

2

Looks like homework. Try to ignore the fact that sa->array is a string array. Try doing this exact operation over an int array.

void insert(SmartArray* sa, int indexWhereInsert, char* stringToInsert){
  // upper bound of indexWhereInsert?
  if( !(0 <= indexWhereInsert && indexWhereInsert < sa->size) ){
    printf("Do something about bounds...");
    return;
  }

  // Lets make sure there is always space
  if( sa->capacity < sa->size+1 ) 
    increaseCapacity(sa); // Usually double it

  // We move all strings at the right of indexWhereInsert one position to the right
  for(int index = sa->size - 1 ; index >= indexWhereInsert; index--){
    sa->array[index+1] = sa->array[index];
  }

  // Finally we insert the new string
  sa->array[indexWhereInsert] = stringToInsert;
  sa->size++;
}

Edit: You should notice that your last item must always be at (sa->size - 1). Then iterate from the end to the position of interest.

Black Arrow
  • 375
  • 3
  • 12
  • That sets the entire string equal to what was being inserted. Is an temp variable necessary in this kind of scenario in order to not override the other values? Also, you transverse through it like a 1D array? I'm just trying to make sure I understand this correctly. :) – starlight Feb 13 '17 at 01:08
  • @starlight But the array *is* a "one-dimensional" array. It is an array of pointers yes, but it's still an single-dimensional array. – Some programmer dude Feb 13 '17 at 01:11
  • I thought it would be a 2D array because of the **. I think this is how I got confused. – starlight Feb 13 '17 at 01:13
  • @starlight Read [this](http://stackoverflow.com/questions/7586702/is-2d-array-a-double-pointer). – RoadRunner Feb 13 '17 at 01:28
  • @RoadRunner Thank you, I will – starlight Feb 13 '17 at 02:22