2010-04-07 7 views
0

J'écris un programme pour vérifier si un port est ouvert dans C. Une ligne en particulier copie l'un des arguments dans un tableau char. Cependant, quand j'essaye de compiler, il indique:C: types incompatibles dans l'affectation

error: incompatible types in assignment

Hérite le code. L'erreur est sur la cession de 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; 
} 

Je suis nouveau à C, donc je ne sais pas pourquoi il le ferait.

Répondre

8

addr est un tableau que vous ne pouvez pas lui affecter directement.

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

Un pointeur sur ce que vous avez passé dans est de retour, mais cette valeur n'est pas nécessaire. L'appel à strncpy seul copiera la chaîne de argv[2] à addr. Remarque: Je remarque parfois que vous passez l'adresse de votre tableau et que vous passez parfois dans le tableau sans l'adresse de l'opérateur.

Lorsque le paramètre ne demande que char* ...

Bien que les deux fonctionneront en passant addr au lieu de &addr est plus correcte. &addr donne un pointeur vers un tableau char char (*)[1023] tandis que addr vous donne un char* qui est l'adresse du premier élément. Cela n'a généralement pas d'importance, mais si vous faites de l'arithmétique de pointeur, cela fera une grande différence.

+0

Alors, comment puis-je changer pour résoudre ce problème? –

+0

La réponse vous dit ... les deux le font. –

0

une alternative est d'utiliser un char * au lieu:

char *addr; 

addr = strdup(argv[2]); 

strdup est essentiellement un raccourci qui fait un malloc et un strcpy, et vous n'avez pas à vous soucier de la taille d'adr dès le départ. N'oubliez pas d'ajouter ADR une fois que vous avez terminé.
Notez que si argv [2] est NULL, vous obtiendrez un segfault.

+0

strndup serait une bien meilleure idée de se prémunir contre un débordement de buffer. – wadesworld

1

La ligne

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

doit être juste

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

Notez que strncpy ne pas nul-fin si la limite est atteinte 1023 donc vous devriez également avoir

addr[1023] = `\0`; 

Cependant, je suppose qu'il y a d'autres hypothèses dans le code.

5

Vous avez reçu quelques réponses qui répondent exactement à vos questions. Mon conseil serait de prendre du recul et d'éliminer cette étape, car c'est complètement inutile.Je changerais ces lignes:

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 */ 

à quelque chose comme ceci:

struct sockaddr_in address = {0}; 

address.sin_port = htons(atoi(argv[1]));   
address.sin_addr.s_addr = inet_addr(argv[2]); 

Le code existant est en train de faire beaucoup de copies inutiles, ce qui rend le code plus grand et plus lent sans accomplir quoi que ce soit.

Edit: regarder à nouveau, vous devriez probablement ajouter un peu d'erreur de vérification du code (avant ce qui est ci-dessus), quelque chose comme:

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