代码之家  ›  专栏  ›  技术社区  ›  The.Anti.9

C:赋值中的不兼容类型

c
  •  0
  • The.Anti.9  · 技术社区  · 15 年前

    我正在写一个程序来检查C语言中是否有一个端口是打开的,其中一行将一个参数复制到一个字符数组中。然而,当我试图编译时,它说:

    错误:中的不兼容类型 分配

    这是密码。错误在于 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 回复  |  直到 15 年前
        1
  •  8
  •   Brian R. Bondy    15 年前

    addr 是一个数组,因此不能直接分配给它。

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

    将返回指向传入内容的指针,但不需要此值。呼唤 strncpy 只需从 argv[2] ADDR .


    注意:我注意到有时候你传入数组的地址,有时候你传入数组本身时没有操作符的地址。

    当参数只要求 char*

    尽管两个都可以通过 ADDR 而不是 &addr 更正确。 &ADDR 提供指向char数组的指针 char (*)[1023] 反之 ADDR 给你一个 烧焦* 这是第一个元素的地址。这通常不重要,但如果你做指针算术,它会有很大的不同。

        2
  •  5
  •   N 1.1    15 年前

    你已经得到了几个答案,正是你所要求的。我的建议是退后一步,取消这一步,因为这完全没有必要。我要改这几行:

    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;
    }
    
        3
  •  1
  •   Grumdrig    15 年前

    线

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

    应该是公正的

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

    注意,如果达到1023限制,strncpy不为null终止,因此您还应该

    addr[1023] = `\0`;
    

    尽管我认为代码中也有其他假设。

        4
  •  0
  •   Sylvain    15 年前

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

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

    strdup基本上是一个执行malloc和strcpy的快捷方式,您不必担心前面addr的大小。 完成后别忘了释放addr。
    注意,如果argv[2]为空,则会得到segfault。