C: несовместимые типы в присваивании - PullRequest
0 голосов
/ 07 апреля 2010

Я пишу программу для проверки, открыт ли порт в C. Одна строка в частности копирует один из аргументов в массив char. Тем не менее, когда я пытаюсь скомпилировать, он говорит:

ошибка: несовместимые типы в Назначение

Вот код. Ошибка при присвоении 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;
}

Я новичок в C, поэтому я не уверен, почему он это сделает.

Ответы [ 4 ]

8 голосов
/ 07 апреля 2010

addr - это массив, поэтому вы не можете назначить его напрямую.

Измените addr = strncpy(addr, argv[2], 1023); на strncpy(addr, argv[2], 1023);

Возвращается указатель на то, что вы передали, ноэто значение не нужно.Один только вызов strncpy скопирует строку из argv[2] в addr.


Примечание: я замечаю, что иногда вы передаете адрес вашего массива, а иногда вы передаете сам массивбез адреса оператора.

Когда параметр запрашивает только char* ...

Хотя оба будут работать, передавая addr вместо &addr, более правильно.&addr дает указатель на массив символов char (*)[1023], тогда как addr дает вам char*, который является адресом первого элемента.Обычно это не имеет значения, но если вы сделаете арифметику с указателями, это будет иметь большое значение.

5 голосов
/ 07 апреля 2010

Вы получили пару ответов, которые точно соответствуют тому, что вы спрашивали.Мой совет - сделать шаг назад и просто исключить этот шаг, так как он совершенно не нужен.Я бы изменил эти строки:

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

на что-то вроде этого:

struct sockaddr_in address = {0};

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

Существующий код выполняет много ненужного копирования, делая код больше и медленнее, не выполняя ничего.

Редактировать: глядя на это снова, вы, вероятно, должны добавить немного кода проверки ошибок (до того, что выше), что-то вроде:

if (argc != 3) {
    fprintf(stderr, "Usage: %s <port_num> <address>", argv[0]);
    return EXIT_FAILURE;
}
1 голос
/ 07 апреля 2010

Линия

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

должно быть просто

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

обратите внимание, что strncpy не завершается нулем, если достигнут предел 1023, поэтому вы также должны иметь

addr[1023] = `\0`;

хотя я полагаю, что в коде сделаны и другие предположения.

0 голосов
/ 07 апреля 2010

альтернатива - использовать вместо этого символ *:

char *addr;

addr = strdup(argv[2]);

strdup - это, по сути, ярлык, который выполняет malloc и strcpy, и вам не нужно беспокоиться о размере addr заранее. Не забудьте освободить адрес, когда закончите.
Обратите внимание, что если argv [2] равен NULL, вы получите ошибку сегмента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...