Tutorial :C: incompatible types in assignment



Question:

I'm writing a program to check to see if a port is open in C. One line in particular copies one of the arguments to a char array. However, when I try to compile, it says:

error: incompatible types in assignment

Heres the code. The error is on the assignment of addr

#include <sys/socket.h>  #include <sys/time.h>  #include <sys/types.h>  #include <arpa/inet.h>  #include <netinet/in.h>  #include <errno.h>  #include <fcntl.h>  #include <stdio.h>  #include <netdb.h>  #include <stdlib.h>  #include <string.h>  #include <unistd.h>    int main(int argc, char **argv) {    u_short port;                /* user specified port number */    char addr[1023];             /* will be a copy of the address entered by u */    struct sockaddr_in address;  /* the libc network address data structure */    short int sock = -1;         /* file descriptor for the network socket */      port = atoi(argv[1]);    addr = strncpy(addr, argv[2], 1023);    bzero((char *)&address, sizeof(address));  /* init addr struct */    address.sin_addr.s_addr = inet_addr(addr); /* assign the address */    address.sin_port = htons(port);            /* translate int2port num */      sock = socket(AF_INET, SOCK_STREAM, 0);    if (connect(sock,(struct sockaddr *)&address,sizeof(address)) == 0) {      printf("%i is open\n", port);    }    if (errno == 113) {      fprintf(stderr, "Port not open!\n");    }    close(sock);    return 0;  }  

I'm new to C, so I'm not sure why it would do this.


Solution:1

addr is an array so you can't assign to it directly.

Change addr = strncpy(addr, argv[2], 1023); to strncpy(addr, argv[2], 1023);

A pointer to what you passed in is returned, but this value isn't needed. The call to strncpy alone will copy the string from argv[2] to addr.


Note: I notice sometimes you pass in the address of your array and sometimes you pass in the array itself without the address of operator.

When the parameter only asks for char*...

Although both will work passing in addr instead of &addr is more correct. &addr gives a pointer to a char array char (*)[1023] whereas addr gives you a char* which is the address of the first element. It usually doesn't matter but if you do pointer arithmetic then it will make a big difference.


Solution:2

You've gotten a couple of answers that address exactly what you asked. My advice would be to step back and just eliminate that step, as it's completely unnecessary. I'd change these lines:

u_short port;                /* user specified port number */  char addr[1023];             /* will be a copy of the address entered by u */  struct sockaddr_in address;  /* the libc network address data structure */    port = atoi(argv[1]);  addr = strncpy(addr, argv[2], 1023);  bzero((char *)&address, sizeof(address));  /* init addr struct */  address.sin_addr.s_addr = inet_addr(addr); /* assign the address */  address.sin_port = htons(port);            /* translate int2port num */  

to something like this:

struct sockaddr_in address = {0};    address.sin_port = htons(atoi(argv[1]));          address.sin_addr.s_addr = inet_addr(argv[2]);  

The existing code is doing a lot of unnecessary copying, making the code bigger and slower without accomplishing anything.

Edit: looking at it again, you should probably add a bit of error checking code (before what's above), something like:

if (argc != 3) {      fprintf(stderr, "Usage: %s <port_num> <address>", argv[0]);      return EXIT_FAILURE;  }  


Solution:3

The line

addr = strncpy(addr, argv[2], 1023);  

should be just

strncpy(addr, argv[2], 1023);  

note that strncpy doesn't null-terminate if the 1023 limit is reached so you should also have

addr[1023] = `\0`;  

though I suppose there's other assumptions made in the code as well.


Solution:4

an alternative is to use a char * instead:

char *addr;    addr = strdup(argv[2]);  

strdup is basically a shortcut that does a malloc and a strcpy, and you don't have to worry about the size of addr upfront. Don't forget to free addr once you're done.
Note that if argv[2] is NULL you will get a segfault.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »