Incompatible types in assignment - C - 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]));

Related

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], ""))

Two errors I'm getting in this C program. Deals with structures, arrays, and bubble sorting

First two errors:
cs1713p3.c:129: error: incompatible types in assignment
cs1713p3.c:131: error: conversion to non-scalar type requested
Lines 129 and 131 are parts of a bubble sort function I wrote, which is meant to sort an array of a structure called "Stock". Here's the code for the Stock structure:
typedef struct
{
char szStockNumber[7]; // Stock Number for a stock item
long lStockQty; // quantity in stock
double dUnitPrice; // price per unit of stock
char szStockName[31]; // name of the stock item
} Stock;
Here's the code I wrote for the sort:
void sortInventory(Stock stockM[], int iStockCnt)
{
Stock *temp;
int i;
int j;
int bChange = 1;
for(i = 0; i < (iStockCnt - 1) && bChange == 1; i++)
{
bChange = 0;
for(j = 0; j < (iStockCnt - i - 1); j++)
{
if(strcmp(stockM[i+1].szStockNumber, stockM[i].szStockNumber) < 0)
{
temp = stockM[i]; //line 129
stockM[i] = stockM[i+1];
stockM[i+1] = (Stock)temp; //line 131
bChange = 1;
}
}
}
}
Yeah, I tried typecasting each assignment with a (Stock) right after the equals sign in each line, but that didn't work.
Thanks to anyone who helps out! I have no clue what's going wrong and I can't seem to find any relevant information on the internet, I think it's too specific of a case, haha.
stockM is an array of type Stock. temp, on the other hand, is an array of type Stock*. So, you are basically trying to assign the value of a variable of type Stock to a variable of type Stock* which is not allowed.
Change the type of temp to Stock.

Error while printing Nodes in C?

I am trying to print what I have in nodes but it says the following error
main.c: In function 'main':
main.c:83:37: error: request for member 'emails' in something not a structure or union
printf("%s\n", tmpNodesUnique[l].emails);
^
I get the above error after I run the following code. What am I doing wrong here?
Node *tmpNodesUnique[nodesCount];
int uniqueFound = 0;
tmpNodesUnique[0] = &tmpNodes[0];
for (k=1; k<10; k++){
if (strcmp(tmpNodesUnique[uniqueFound]->emails, tmpNodes[k].emails) != 0){
tmpNodesUnique[++uniqueFound] = &tmpNodes[k];
}
}
for (k=0; k<=uniqueFound; k++){
tmpNodesUnique[k]->emails;
}
for(l = 0; l <= nodesCount; l++){
printf("%s\n", tmpNodesUnique[l]->emails);
}
Probably your struct Node is defined as
typedef struct {
char *emails;
} Node;
This means if you want to print the member emails you will have to use . operator and not the -> operator
for(l = 0; l <= nodesCount; l++){
printf("%s\n", tmpNodesUnique[l].emails);
}
And as pointed out in the comments the following line does nothing, it is an incomplete statement
for (k=0; k<=uniqueFound; k++){
tmpNodesUnique[k]->emails;
}
Additionally make sure you really want k<= instead of k< it looks suspicious as well
It looks like you're not compiling the code you expect.
The error uses a . member operator for emails. While you have a -> pointer operator in the code you show. So the code is different (and the error is related to the dot as it's stating that it expects a structure or union member while you've clearly declared a pointer).

pointer to array assignment in 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;
}

Undefined reference to function - Learning C

I'm learning C by translating some of the things I have done in Python to C. I have tried to look online as much as I can before coming here but it seems really difficult to find answers to what I'm looking for.
What follows is my (so-far) translation of the Miller-Rabin test for a number's primality.
#include <stdio.h>
#include <math.h>
_Bool prime(long long n);
int main() {
int i = 6;
for (i; i < 9; i++) {
if (prime(i)) {
printf("%i\n", prime(i));
}
}
}
_Bool prime(long long n) {
int s = 0;
int r = 0;
int a_index = 0;
// printf("the value of a_index when initialised is: %d\n", a_index);
// printf("the value of s when initialised is: %d\n", s);
int *a_list;
_Bool is_prime = 1;
_Bool composite_part_a = 1;
_Bool composite_part_b = 1;
long long d = n - 1;
while (d % 2 == 0) {
s++;
d = d / 2;
}
if (4759123141 <= n && n < 2152302898747) {
// malloc
a_list[0] = 2;
a_list[1] = 3;
a_list[2] = 5;
a_list[3] = 7;
a_list[4] = 11;
}
else if (9080191 <= n && n < 4759123141) {
// malloc
a_list[0] = 2;
a_list[1] = 7;
a_list[2] = 61;
}
else if (1373653 <= n && n < 9080191) {
// malloc
a_list[0] = 31;
a_list[1] = 73;
}
else if (4 <= n && n < 1373653) {
a_list = (int *) malloc(sizeof(int) * 2);
a_list[0] = 2;
a_list[1] = 3;
printf("the value of a_list[0] upon its first assignment is: %d\n", a_list[0]);
// printf("the first element of a_list is: %d\n", a_list[0]);
// printf("the second element of a_list is: %d\n", a_list[1]);
}
else if (n == 3 | n == 2) {
return 1;
}
else if (n % 2 == 0 | n == 1) {
return 0;
}
printf("the value of a_list[0] over here is: %d\n", a_list[0]);
// printf("%d\n", a_list[1]);
for (a_index; a_index < sizeof(a_list) / sizeof(int); a_index++) {
printf("test");
if ((long long)pow(a_index[a_list], d) % n != 1) {
composite_part_a = 1;
}
else {
composite_part_a = 0;
}
// printf("the value of r is: %d\n", r);
// printf("the value of s is: %d\n", s);
for (r; r < s; r++) {
printf("%lld\n", (int)pow(a_list[a_index], exp2(r) * d) % n);
if ((long long)pow(a_index[a_list], exp2(r) * d) % n != -1) {
composite_part_b = 1;
}
else {
composite_part_b = 0;
break;
}
}
if (composite_part_a && composite_part_b) {
return 0;
}
}
return is_prime;
}
The trouble with learning C is there isn't much good literature for pure beginners, outside of what I hear about K&R but that's in the mail and I can't get my hands on it right now. The program returns these errors:
3.c: In function ‘prime’:
3.c:52:26: warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]
/tmp/ccGQnk9T.o: In function `prime':
3.c:(.text+0x272): undefined reference to `pow'
3.c:(.text+0x2b9): undefined reference to `exp2'
3.c:(.text+0x2db): undefined reference to `pow'
3.c:(.text+0x30b): undefined reference to `exp2'
3.c:(.text+0x32d): undefined reference to `pow'
collect2: ld returned 1 exit status
First off, haven't I included to introduce pow and else? I know it's not proper to ask two questions and my main question is about pow and exp2, but if you do have a suggestion about the malloc as well feel free to include it.
You need to link with the math library as well, it's not included by default.
Something like the following command:
$ gcc 3.c -lm
Notice the -lm argument... It tells the linker to add a library (the -l part) and the name of the library (the m part).
Math functions are part of libm. Link them when you compile with -lm.
3.c:52:26: warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]
Is caused by a missing include, malloc() is defined in stdlib.h so need to include that.
3.c:(.text+0x272): undefined reference to `pow' (and the rest)
Is caused by a missing link to libm. Most (if not all) methods in math.h are not in standard libc that always gets linked but in libm instead.
How to link differs between compiler, but for gcc (and many other unix compilers):
gcc 3.c -o 3 -lm
Where "-lm" tells gcc to link libm.
You need to include <stdlib.h> for malloc and free.
For the math stuff to work you have to link it,
gcc 3.c -lm
Where -l is the library flag and m is tell it to use the math library
Also you need to move the definition of prime to above main, things need to be declared in order.
Since you are just starting here are some other helpful flags for the compiler
-g this will give better debugging when using valgrind or gdb.
-o lets you define the compiled file name eg: gcc 3.c -o 3 will create ./3 instead of ./a.out

Resources