【问题标题】:C: incompatible types in assignmentC:赋值中不兼容的类型
【发布时间】:2010-04-07 04:23:34
【问题描述】:

我正在编写一个程序来检查一个端口是否在 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 新手,所以我不确定它为什么会这样做。

【问题讨论】:

    标签: c


    【解决方案1】:

    addr 是一个数组,所以不能直接赋值给它。

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

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


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

    当参数只要求char*...

    虽然两者都可以通过 addr 而不是 &amp;addr 更正确。 &amp;addr 给出了一个指向 char 数组 char (*)[1023] 的指针,而 addr 给出了一个 char*,它是第一个元素的地址。这通常没关系,但如果你做指针算术,那么它会有很大的不同。

    【讨论】:

    • 那么我该如何改变它来修复它?
    • 答案告诉你......他们都这样做。
    【解决方案2】:

    您已经得到了几个答案,这些答案完全符合您的要求。我的建议是退后一步,只是消除这一步,因为这完全没有必要。我会改变这些行:

    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】:

      线

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

      应该只是

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

      请注意,如果达到 1023 限制,strncpy 不会以空值终止,因此您也应该拥有

      addr[1023] = `\0`;
      

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

      【讨论】:

        【解决方案4】:

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

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

        strdup 基本上是一个执行 malloc 和 strcpy 的快捷方式,您不必预先担心 addr 的大小。 完成后不要忘记释放地址。
        请注意,如果 argv[2] 为 NULL,您将收到段错误。

        【讨论】:

        • strndup 是防止缓冲区溢出的更好主意。
        猜你喜欢
        • 2013-05-15
        • 2012-09-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-12
        • 2021-06-07
        • 2012-03-13
        • 2017-03-26
        相关资源
        最近更新 更多