0

I've been stuck at this for a while.

Let there be an array of strings declared by user:

#define LENGTH 3

int main()
{
  char* hohoho[3]={"string1","string2","string3"};
  foo1(hohoho);
  for(i=0; i<LENGTH-1; i++)
    {
        printf("%s, ",hohoho[i]);
    }
  printf("%s.",hohoho[LENGTH-1]);
  return 0;
}

  foo1(char** array);
{
/*moving array 1 time left and placing first one at the end*/
}

expected: string2, string3, string1.

I have tried changing strings with a tmp *char, I have tried changing them by address, cant find info on the web on how to approach this exercise. to my understanding I cant change the strings themselves because they are considered to be only read strings. I cannot use malloc or any helping array for that matter.

jxh
  • 69,070
  • 8
  • 110
  • 193
  • `"string1","string2","string3"` are *String-Literals* that reside in read-only memory on standards conforming systems. `hohoho` is an array of pointers to string-literals. You need `char hohoho[3][10] = {...}` if you intend to manipulate the content of the strings. `foo` will then be `foo1(char (*)[10] array);` See also: [C11 Standard - §5.1.2.2.1 Program startup(p1)](http://port70.net/~nsz/c/c11/n1570.html#5.1.2.2.1p1). See also: [What should main() return in C and C++?](http://stackoverflow.com/questions/204476/) – David C. Rankin Dec 28 '20 at 02:52
  • For `LENGTH` you mean `3` isn't it? – anotherOne Dec 28 '20 at 02:53
  • As written you CAN swap pointers in `foo()`. – David C. Rankin Dec 28 '20 at 02:55
  • @DavidC.Rankin yes LENGTH is 3 sorry forgot to mention that, i cant change the initial array declaration so it must be a char* [] also, i cant use brackets, its a pointer only exercise. – michael dest Dec 28 '20 at 02:57
  • also the link you posted is broken :( – michael dest Dec 28 '20 at 03:01
  • 1
    Then in `foo1()` you want `char *tmp = array[0]; array[0] = array[2]; array[2] = tmp;` – David C. Rankin Dec 28 '20 at 03:01
  • See [C11 Standard - 5.1.2 Execution environments](http://port70.net/~nsz/c/c11/n1570.html#5.1.2) and next 2 sections. – David C. Rankin Dec 28 '20 at 03:03
  • Based on your current code, it seems what you want is covered here more or less: https://stackoverflow.com/questions/65376006/how-can-i-swap-two-strings-in-a-string-array-of-pointers-in-c-without-using-othe/65376520#65376520 – costaparas Dec 28 '20 at 03:04
  • 1
    @costaparas that's exactly what i need just a bit simpler, amazing thank you! – michael dest Dec 28 '20 at 03:13

2 Answers2

0

array is a pointer to the array containing pointers to the strings, so you can change the pointers in the array from the function.

From this point it's just a matter of how to shuffle the pointers the way you want. This is basically a longer version of swapping two variables, as in:

tmp_s = s1;
s1 = s2;
s2 = tmp_s;

If these were in an array, it would look like:

tmp_s = s[0];
s[0] = s[1];
s[1] = tmp_s;

Since you have an array of multiple values, you'll need a loop for the middle part (s[i] = s[i+1]). The complication here is that you need to know the length of the array. Normally that would be another value passed in to your foo1() function, or the array would have a placeholder value indicating the end of values (e.g. a = {"a", "b", "c", NULL}).

If you're not allowed to change the array declaration or function parameters, you'll just have to assume the array length a constant - looks like LENGTH is defined to be 3 so you can use that.

John Bayko
  • 746
  • 4
  • 7
0

Though I don't understand your "moving array 1 time left" comment, I presume it means rotate all elements to the left by 1 so you end up with "string2", "string3", "string1", and then swapping first/last would end up with "string1", "string3", "string2" (effectively swapping the 2nd and 3rd elements as the final result)

As mentioned, you have an array-of-pointers-to string-literals, so the content of the strings is immutable, but you can swap the order of the pointers. If you take the logic above, and apply the left-rotate and swap first/last your foo1() function could be:

void foo1 (char **array)
{
    /*moving array 1 time left and placing first one at the end*/
    char *tmp = array[0];
    
    for (int i = 1; i < LENGTH; i++)    /* move all elements left by 1 */
        array[i-1] = array[i];
    array[LENGTH-1] = tmp;
    
    tmp = array[0];                     /* swap 1st and last */
    array[0] = array[LENGTH-1];
    array[LENGTH-1] = tmp;
}

(note: if you don't need the left-rotate of elements, you can delete that part of the code)

If you add the header required, the full code could be written as:

#include <stdio.h>

#define LENGTH 3

void foo1 (char **array)
{
    /*moving array 1 time left and placing first one at the end*/
    char *tmp = array[0];
    
    for (int i = 1; i < LENGTH; i++)    /* move all elements left by 1 */
        array[i-1] = array[i];
    array[LENGTH-1] = tmp;
    
    tmp = array[0];                     /* swap 1st and last */
    array[0] = array[LENGTH-1];
    array[LENGTH-1] = tmp;
}

int main (void) {

    char *hohoho[] = {"string1", "string2", "string3"};
    
    puts ("original order:");
    for (int i=0; i<LENGTH; i++)
        puts (hohoho[i]);
    
    foo1 (hohoho);
    
    puts("\norder after rotating left 1 and swapping first/last:");
    for (int i=0; i<LENGTH; i++)
        puts (hohoho[i]);
    
    printf ("\n%s.\n", hohoho[LENGTH-1]);
}

Example Use/Output

$ ./bin/swap_arr_of_ptrs
original order:
string1
string2
string3

order after rotating left 1 and swapping first/last:
string1
string3
string2

string2.

(no idea why you include the last output, but it was there...)

Look things over and let me know if I have the logic of the "moving array 1 time left" part wrong or if you have further questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85