It may be easier to see the problem if we rewrite the function using subscript notation instead of *(pt+i).
void sort_strlen(char (*pt)[81]){
char (*temp)[81];
int i, j;
for(i = 0; i < 10 && pt[i] != NULL; i++)
for(j = i + 1; j < 10 && pt[j] != NULL; j++)
if(strlen(pt[i]) < strlen(pt[j])){
temp = pt[i];
pt[i] = pt[j];
pt[j] = temp;
}
for(i = 0; i < 10 && pt[i] != NULL; i++)
puts(pt[i]);
}
So when you're trying to swap pt[i] and pt[j], first you try to assign a char* (to which the char[81] pt[i] is automatically converted here) to a char(*)[81] in the temp = pt[i]; line.
The type incompatibility should be clear here. But usually, that one's only a warning and "works as intended" because pt[i] is converted to the address of the first byte in that string, which also is the address of the array pt[i]. The warning would vanish if the type of the right hand side is adjusted by assigning &pt[i] or pt + i.
The errors are on the next lines. In the pt[i] = pt[j]; line, you try to assign a char* to a char[81], and in the pt[j] = temp; line, you try to assign a char(*)[81] to a char[81].
Arrays are not assignable, so writing
pt[i] = ...
is always an error. It is unfortunate that gcc reports that as
sort_strlen.c:13:18: error: incompatible types when assigning to type ‘char[81]’ from type ‘char *’
sort_strlen.c:14:18: error: incompatible types when assigning to type ‘char[81]’ from type ‘char (*)[81]’
and not the more immediately pointing to the root cause
sort_strlen.c:13:18: error: array type 'char [81]' is not assignable
*(pt + i) = *(pt + j);
~~~~~~~~~ ^
sort_strlen.c:14:18: error: array type 'char [81]' is not assignable
*(pt + j) = temp;
~~~~~~~~~ ^
that clang emits. The "incompatible types" that gcc reports are principally unfixable since no type on the right hand side is compatible with an array type on the left hand side of an assignment.
I solved the problem by creating an array of pointers. I wanted to sort the strings directly by changing their addresses inside the array. Does anybody knows if it possible ? What is the best way to do it ?
That depends what you want to do. You can't change the addresses of the strings without moving the strings themselves around, you would do that for example with
char temp[81];
...
strcpy(temp, pt[i]);
strcpy(pt[i], pt[j]);
strcpy(pt[j], temp);
If you don't want to move the strings around, you would indeed best create an array of pointers
char *strings[10];
for(int i = 0; i < 10; ++i) {
strings[i] = pt[i]; // make it &pt[i][0] if you don't like the implicit conversion
}
and sort the strings array by string length:
char *temp;
...
if (strlen(strings[i]) < strlen(strings[j])) {
temp = strings[i];
strings[i] = strings[j];
strings[j] = temp;
}
*(pt + i)points to is bigger than the one just after (*(pt + j)), I would like to interchange the addresses where the two pointers point to. However, gcc doesn't accept it. I could only solve the problem by adding an array of pointer to char where I store the addresses of each string and then interchange the addresses inside that array. Is there a better way to do the job ?