1

To swap two elements in a normal char array, I know this function will work

void swap(char str[],int i, int j){
    char c=str[i];
    str[i]=str[j];
    str[j]=c;
}

I tried something similar with a 2 dimensional array, but got this statement "error: assignment to expression with array type". This is the function I tried to use.

void swap(char name[][31],int i,int j){
    char hold[31];
    hold=name[i];
    name[i]=name[j];
    name[j]=hold;
}

I'm really new to coding and I'm trying to learn as much on my own before I enter a tertiary institution.

I am trying to figure out how to write a function to swap two rows in a 2 dimensional array.

Marcin Krysiak
  • 336
  • 4
  • 10
  • 1
    You could write a loop that swaps each corresponding pair of elements of the rows. – Scott Hunter Sep 01 '20 at 18:55
  • `hold` does not need to be an array. Make it `char hold = 0;`. The function will then compile. and if placed in a loop: `for(i=0;i – ryyker Sep 02 '20 at 12:53

3 Answers3

2

You have the right idea, i.e using a hold variable of the same type to contain intermediate result while transferring the two array rows, but a couple of things to address first:

As mentioned in the comments, hold does not need to be an array. That simple fix will allow your function to be called in a loop. This is an example with minor edits to illustrate your function, and how it would be called:

int main(void)
{
    char names[][31] = {{"THIS STRING IS UPPER CASE"},{"this string is lower case"}}; 

    for(int i = 0;i<sizeof(names[0])/sizeof(names[0][0]);i++)
    {
        swap(names, i, i);//must be called in loop to complete swap
    }
}    
//swaps one char per call and returns    
void swap(char name[][31],int i,int j)
{
    char hold;
    
    hold=name[0][i];
    name[0][i]=name[1][j];
    name[1][j]=hold;
}

Suggestions on style
For efficiency, readability and maintainability it is often better to move as much work related to a function into the function itself. In this case, rather then looping on swap 31 times, by making a change to the argument list, and moving the looping into the function, it can be called once, and still provide the desired result.

The following is an example of your method, but adapted to do all work internally. Note changes to the argument list.

//adaptation of original method with internal looping
void swap1(char **str)
{
    int len = strlen(str[0]);//same len, test one.
    
    char hold = 0;
    
    for(int i = 0;i < len;i++)
    {
        hold = str[0][i];
        str[0][i] = str[1][i];
        str[1][i] = hold;
    }        
}

And, per suggestion in comments, if char arrayare each\0` terminated, they qualify as a pair of C strings, allowing use of the string function strcpy() to simplify by removing need to loop.

//using strcpy() to simplify swap 
void swap2(char **str)
{
    int len = strlen(str[0]);//same len, test one.
    
    char hold[len+1];
    
    strcpy(hold, str[0]);
    strcpy(str[0], str[1]);
    strcpy(str[1], hold);
}

Finally, the following shows the new calling method, used for both variations:

void swap1(char **str);//char by char
void swap2(char **str);//use strcpy()

int main(void)
{  
    //char name[2][80] = {{"name1IsLongerThan2"}, {"Name2IsShorter"}};
    char *name1 = "name1IsLongerThan2";
    char *name2 = "Name2IsShorter    ";//Note for this example, 
                                       //both strings must be same length
    char *name[] = {name1, name2};
    
    swap1(name);
    printf("name 1: %s\nname 2: %s\n", name[0], name[1]);
    swap2(name);
    printf("name 1: %s\nname 2: %s\n", name[0], name[1]);

    return 0;
}
ryyker
  • 22,849
  • 3
  • 43
  • 87
0

As ryyker explains, you cannot assign to an array. But you could organize your data a little differently to allow you do this.

This may be more info than you need right now, so feel free to skip it if it doesn't make sense or doesn't help. You can come back and read it later.

Instead of a 2D array of char, which is an array of arrays of char, you could make an Illife vector (google-able). Where a 2D look like this in memory:

name[0][0]  name[0][1]  name[0][2] ...
name[1][0]  name[1][1]  name[1][2] ...
name[2][0]  name[2][1]  name[2][2] ,,,

and accessing just the first dimension yields an array of the row elements, an Illife vector makes an array of pointers for the first dimension. Each pointer points to its row.

name[0]  -->  [0]  [1]  [2]  ... 
name[1]  -->  [0]  [1]  [2]  ...
...

So the code would look like this, allowing a simple swap of rows. [To make sense of these declarations, search for "C FAQ spiral rule".]

#include <stdio.h>

int main(){
    char (*name[3])[31]; // an array [3] of pointers * to array [31]
    name[0] = &(char[31]){ 'f','i','r','s','t','\0' };
    name[1] = &(char[31]){ 's','e','c','o','n','d','\0' };
    name[2] = &(char[31]){ 't','h','i','r','d','\0' };

    char (*hold)[31];
    hold = name[0];
    name[0] = name[2];
    name[2] = hold;

    for(  int i = 0; i < sizeof name / sizeof name[0]; ++i  ){
        printf( "%s\n", name[i] );
    }
}

Output:

$ make f && ./f
cc     f.c   -o f
third
second
first

You can also organize your data to allow you to swap columns as well, but it gets quite a bit more complicated. Use a dope vector to access arbitrary axial slices of a multidimensional array?

luser droog
  • 18,988
  • 3
  • 53
  • 105
0

According to your query you want to swap 2 rows in a 2 dimensional array. Assuming you're dealing with a 2 dimensional array like this one

 c a
 b d

The key to swap 2 rows in a 2 dimension array is to first loop through the 2 dimensional array and then swap the position of first row to the second row.

void swap(char name[][2],int row,int column)
{
   int hold;
   int rowPosition1=1;
   int rowPosition2=2;

   // swap the 1st row position to the second row
   for(int i=0;i<row;++i)
   {
     hold = name[rowPosition1-1][i];
     name[rowPosition1-1][i] = name[rowPosition2-1][i];
     name[rowPosition2-1][i] = hold;
   }

   // print the final array
   for(int i=0;i<row;++i)
   {
      for(int j=0;j<column;++j)
      {
         printf("%c ",name[i][j]);
      }
      printf("\n");
   }
}

Calling this method in the main function like this

int main()
{
    int row=2;
    int column=2;
    char array1[][2]={{'c','a'},{'b','d'}};
    printf("Matrix before swapping rows.");
    printf("\n");
      
    for(int i=0;i<row;++i)
    {
       for(int j=0;j<column;++j)
       {
          printf("%c ",array1[i][j]);
       }
       printf("\n");
    }  
      
    printf("Matrix after swapping rows.");
    printf("\n");
    swap(array1,2,2);

    return 0;
}

The resultant array will look like this

b d
c a
Nelson Katale
  • 1,309
  • 15
  • 21