C:赋值中不兼容的类型

时间:2010-04-07 04:23:34

标签: c

我正在编写一个程序来检查端口是否在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 个答案:

答案 0 :(得分:8)

addr是一个数组,因此您无法直接分配它。

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

返回指向您传入的内容的指针,但不需要此值。仅对strncpy的调用会将字符串从argv[2]复制到addr


注意:我注意到有时你会传入数组的地址,有时你传入的数组本身没有运算符的地址。

当参数仅询问char* ...

虽然两者都可以传递addr代替&addr更正确。 &addr给出一个指向char数组char (*)[1023]的指针,而addr给出一个char*,它是第一个元素的地址。它通常没关系,但如果你做指针运算,那么它将产生很大的不同。

答案 1 :(得分:5)

你已经得到了几个答案,准确地解决了你的要求。我的建议是退后一步,消除这一步,因为它完全没必要。我会改变这些界限:

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

答案 2 :(得分:1)

该行

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

应该只是

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

请注意,如果达到1023限制,strncpy不会终止,所以你也应该

addr[1023] = `\0`;

虽然我认为代码中还有其他假设。

答案 3 :(得分:0)

另一种方法是使用char *代替:

char *addr;

addr = strdup(argv[2]);

strdup基本上是一个执行malloc和strcpy的快捷方式,您不必担心addr的大小。 一旦完成,不要忘记免费添加 请注意,如果argv [2]为NULL,则会出现段错误。