pointer to array assignment in C - c

I'm a having problem when trying to assign a pointer to array to another pointer to array, please could you tell me where is the problem in the code bellow :
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));
}
GCC return "assigning incompatible types" error when compiling to this function. The problem must be obvious but I'm just a newbie, I can't find the problem by myself.

Is this the line that causes the error? Looks like it. (You should've indicated in your question.)
*(pt + j) = temp;
pt is of type char (*pt)[81] and temp is of the same type. But you dereference pt when you do *(pt + j). (* dereferences a pointer and instead refers to the variable the pointer points to.)
As a result, *(pt + j) is of type char[81]. And that's why it's an error to assign temp to it.
If you know what you're doing, you could get away with this by typecasting. But it appears this is not what you expect so I don't recommend that.

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;
}

Related

Array type 'float [3]' is not assignable .Copying 2d Array in C

I have the following code below:
typedef struct
{
float K[6][3]; //Kalman gain ([row][column])
} FilterData;
void setFilterData(const FilterData *filterdata)
{
FilterData r;
int i;
int i1;
for (i = 0; i < 3; i++) {
for (i1 = 0; i1 < 6; i1++) {
r.K[i1 + 6 * i] = filterdata->K[i + 3 * i1];
}
}
}
Compiling this code leads to the following error:
setFilterData.c: In function setFilterData :
setFilterData.c:25:23: error: assignment to expression with array type
r.K[i1 + 6 * i] = filterdata->K[i + 3 * i1];
What is the alternative here?
Using memcpy explicitly also did not help.
FilterData r;
int i;
for (i = 0; i < 6; i++) {
memcpy(r.K + (3*i),filterdata->K + i,sizeof(float) );
memcpy(r.K + (3*i + 1),filterdata->K + (i+6),sizeof(float));
memcpy(r.K + (3*i + 2),filterdata->K + (i+12),sizeof(float));
}
Your problem is the FilterData.K is defined as a 2-dimensional array, but setFilterData() is treating it as if it were a 1-dimensional array.
The minimual fix is to say
r.K[i1][i] = filterData.K[i1][i]
(this assumes the transposition in your original code is a bug, not a feature, I'll have to read more about Kalman gain to know)
But there's no reason to double for-loop and assign each member separately. You could
memcpy(&r, filterData, sizeof(r))
or better yet
r = *filterData
r.K is a two-dimensional array. This means that r.K[n] is a float array of length 3. You can't assign a value to an array. For example, ask yourself what
int A[5];
A = 6;
would mean. If you want to assign a few to a specific location inside a two-dimensional (or multi-dimensional) array, you have to specify all of the indices.
for (i = 0; i < 3; i++) {
for (i1 = 0; i1 < 6; i1++) {
r.K[i1][i] = ... // I'm not sure what you actually want here.
}
}

copy two arrays of int to one char* in C

I have to arrays of int for example arr1={0,1,1,0,0}, arr2={1,0,1,1,1} and I need to return 1 char* created by malloc that will be shown like this : "01100,10111".
when I do for loop it doesn't work, how can I do it ?
char* ans = (char*)malloc((size * 2+1) * sizeof(int));
for (int i = 0; i < size; i++)
ans[i] = first[i];
ans[size] = ",";
for (int i = size+1; i < 2*size+1; i++)
ans[i] = second[i];
Among the multitude of problems:
Your allocation size is wrong. It should include space for the separating comma and the terminating nullchar. sizeof(int) is wrong regardless, it should be sizeof(char) and as-such can be omitted (sizeof(char) is always 1).
Your storage is wrong. You want to store characters, and your values should be adjusted relative to '0'.
Your indexing of the second loop is wrong.
In reality, you don't need the second loop in the first place:
char* ans = malloc(size * 2 + 2);
for (int i = 0; i < size; i++)
{
ans[i] = '0' + first[i];
ans[size+1+i] = '0' + second[i];
}
ans[size] = ',';
ans[2*size+1] = 0;
That's it.
1.
char* ans = (char*)malloc((size * 2+1) * sizeof(int));
What is size here? It is not defined and declared in the provided code.
You do not need to cast the return value of malloc() to char. In fact, you do not need to cast the return value of malloc() anymore. It is a habit from the early C days.
Why do you need a char pointer here at all exactly? If you want to print 01100,10111 there is no need to use a char pointer for the output of the integer values.
2.
for (int i = 0; i < size; i++)
ans[i] = first[i];
Again what is size here?
What is first here? If it isn´t a pointer this statement is invalid.
3.
ans[size] = ",";
This operation is invalid. You are trying to assign a string to a pointer.
By the way, I don´t know what you trying to do with this statement. You can incorporate the comma separate in the output of 01100,10111, without your intend to include it int the memory of the int arrays itself.
4.
for (int i = size+1; i < 2*size+1; i++)
ans[i] = second[i];
Same as above: What is value and the type of size?
What is second? If it isn´t it a pointer this statement is invalid.
5.
To answer to the question title:
(How to) Copy two arrays of int to one char* in C
This isn´t possible. You can´t copy two arrays with its data to a pointer to char.
There are at least four issues with your code.
You malloc the wrong size, you want to use sizeof(char).
You need to zero terminate it, so you need to add extra room for the terminating zero
char* ans = (char*)malloc((size * 2+2) * sizeof(char));
second[size * 2+1] = 0;
Also the indexing of the second loop is wrong. You are accessing second array out of bounds. Make the loop more like the first.
We also need to convert the integer value to a char in the loops.
for (int i = 0; i < size; i++)
ans[size+i+1] = second[i] + '0';

How do I check if there is an element in a Matrix?

I'm Trying to check in my matrix of dimension [10][10], which spots are available to store data (String) there and which are occupied.
The code basically goes through the whole matrix and checks every spot.
I have tried using the strlen and != NULL but everything just prints that the spot is free.
char parque[10][10];
for(int i = 0; i < 10; i++) {
for(int j = 0; j < 10; j++) {
parque[i][j] = "";
}
}
parque[5][5]="f47ac10b-58cb-4372-a567-0e02b2c3d499,ANR";
for(int i = 0; i < 10; i++) {
for(int j = 0; j < 10; j++) {
if(parque[i][j] != "") {
printf("The Spot [%d][%d] is taken",i,j);
} else {
printf("The Spot [%d][%d] is free",i,j);
}
}
}
Basically the spot [5][5] should print that it's taken, at least that's what I want it to do...
Thanks in advance!
Your declaration
char parque[10][10];
declares a two-dimensional array of char. If you compile your code with a strict compiler, you'll get an error:
error: assignment makes integer from pointer without a cast [-Wint-conversion]
parque[i][j] = "";
^
What you did mean is to make an array of pointers to const char, like here:
const char* parque[10][10];
Then your program will say that The Spot [5][5] is taken.
You can't use !=. You need to use strcmp. And, of course, you need to initialize your array content before iterating it and using its values to compare with "" string.
This condition:
if(parque[i][j] != "")
Will become:
if (strcmp(parque[i][j], ""))

warning: assignment from incompatible pointer type buffer

for(i = 0; i < sizeof(buff); i++) if(buff[i] = ' ') ++num;
char **parts[num];
char *p;
p = strtok(buff, " ");
int j = 0;
while(p != NULL)
{
parts[j] = p;
j++;
p = strtok(NULL, " ");
}
During compiling the warning was raised:
assignment from incompatible pointer type, where parts[j] = p is.
What can I do?
I am assuming that you would like to store individual tokens in an array. As is currently declared, parts is an array of pointers to pointers. That is not what you want for an array of C strings - you need to remove one asterisk:
char *parts[num]; // This requires at least C99
Note that num needs to start at 1, not at 0, because the number of tokens that you are going to get is one greater than the number of spaces that you will find in the string.
Once you do, your program would still need some fixing in the way it deals with results of strtok: you should not store results for use after the next call of strtok, because these results become invalid. Instead, you should make duplicates of tokens before storing them in the parts array:
parts[j] = strdup(p);
char *parts[num];
you can declare a pointer to the array of pointers declared above like so:
char *(*ptr)[num] = &parts;
but you don't need this extra level of indirection to store an array of strings
Do you use this line in your actual code?
for(i = 0; i < sizeof(buff); i++) if(buff[i] = ' ') ++num;
You are setting entire buffer to spaces. And setting num to sizeof(buff)
So, in other words this might not position you where you want:
char **parts[num];

Incompatible types in assignment - C

I'm trying to sort an array of strings, but my compiler keeps saying I have imcompatible types in my assignment.
Below is the code in question.
for(i = 0; i < 499; i++) {
max = 0;
for(j = 1; j < 500; j++) {
if(strncmp(user_id[max], user_id[j], 9) > 0) {
printf("max = %s, j = %s\n", user_id[max], user_id[j]);
temp = user_id[j];
user_id[j] = user_id[max];
user_id[max] = temp;
}
}
}
The following two lines throw the error:
user_id[j] = user_id[max];
user_id[max] = temp;
Why is it that I am receiving this error?
EDIT:
Sorry, I forgot to include this before.
char user_id[500][9];
char* temp;
i j and max are int.
rover-208-149:prog3 kubiej21$ gcc --ansi --pedantic -o prog3 prog3.c
prog3.c: In function ‘main’:
prog3.c:46: error: incompatible types in assignment
prog3.c:47: error: incompatible types in assignment
Arrays are not assignable in C. So the following is not valid:
char user_id[500][9];
user_id[23] = user_id[42]; // Error: trying to assign array
I'm not sure what you're trying to achieve, but perhaps memcpy is what you need?
memcpy(user_id[23], user_id[42], sizeof(user_id[23]));

Resources