c - 如何将 char[ ] 转换为 char * ?

标签 c arrays pointers

我想知道如何将 char[] 数组转换为 char *

例如,在我的代码中,我尝试使用“example.com”等主机名访问 Web 服务器

使用我的代码,如果我将 char * 设置为“example.com”,如下所示,它可以完美运行。

char *host = "example.com";

但是,我真正想做的是能够使用套接字从客户端程序读取数据,写入 char[] 数组,并使用从中获取的数据作为主机名。

例如,

char buffer[4096], hostname[4096]; 

bzero(buffer, 4096);
n = read(newsockfd, buffer, 4095);

strcpy(hostname, buffer);
printf("Here is the hostname: %s\n", &hostname[0]);

int sockwb, wbport, x;
struct sockaddr_in webser_addr;
struct hostent *wbhost;
char webbuf[4096];//sending to webserver

wbport = 80;//port used to access web server

sockwb = socket(AF_INET, SOCK_STREAM, 0);

wbhost = gethostbyname(hostname);

当我的代码到达最后一行时,它只是坐在那里,所以我认为这是一个打字问题,因为当我这样做时:

char *host = "example.com";

...

wbhost = gethostbyname(host);

它可以工作,并且能够从网络获取数据并将其正确发送到我的客户端程序。

任何想法都会受到赞赏。

在客户端程序中,我使用 fgets() 从 stdin 读取 char[],然后使用 write() 写入套接字以供服务器程序读取。在写入套接字之前,我曾尝试使用 strcat() 将 '\0' 添加到 char[] 的末尾,但这似乎没有做任何事情

完整代码:(请忽略评论,现在只是尝试不同的事情) 客户端

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>


int main(int argc, char *argv[])
{

  int sockfd, portnum, n;
  struct sockaddr_in serv_addr;
  struct hostent *server;

  char buffer[4096];

  if(argc < 3)
  {
    fprintf(stderr, "usage %s hostname port\n", argv[0]);
    exit(1);
  }

  portnum = atoi(argv[2]);
  sockfd = socket(AF_INET, SOCK_STREAM, 0);

  if(sockfd < 0)
  {
    perror("ERROR opening Socket");
    exit(1);
  }

  server = gethostbyname(argv[1]);

  if(sockfd  == NULL)
  {
    fprintf(stderr, "ERROR, no such host\n");
    exit(1);
  }

  bzero((char *) &serv_addr, sizeof(serv_addr));

  serv_addr.sin_family = AF_INET;
  bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);

  serv_addr.sin_port = htons(portnum);

  if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
  {
    fprintf(stderr, "ERROR, on connecting");
    exit(1);
  }

  printf("Please enter the Host name: ");
  bzero(buffer, 4096);
  fgets(buffer, 4095, stdin);
  //strcat(buffer, "\0");

  n = write(sockfd, buffer, strlen(buffer));

  if(n < 0)
  {
    printf("Error writing to socket");
    exit(1);
  }

  bzero(buffer, 4096);
  n = read(sockfd,buffer, 4095);

  if(n < 0)
  {
    printf("ERROR reading from socket");
    exit(1);
  }
  printf("%s\n", buffer);

  return 0;
}

服务器

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <netdb.h>
#include <string.h>



int main(int argc, char *argv[])
{

    int sockfd, newsockfd, portnum, clilen;
    char buffer[4096], hostname[4096];
    pid_t p_id;
    struct sockaddr_in serv_addr, cli_addr;
    int n, pid, hostname_len;
    //char *host;
    char *host = "example.com";

    if(argc < 2)
    {
        fprintf(stderr, "ERROR, NO PORT PROVIDED!\n");
        exit(1);
    }

    sockfd = socket(AF_INET, SOCK_STREAM, 0);//socket is made

    if(sockfd < 0)
    {
        fprintf(stderr, "ERROR opening socket!!");
        exit(1);
    }

    bzero((char *) &serv_addr, sizeof(serv_addr));
    portnum = atoi(argv[1]);//port num

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(portnum);


    if(bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
    {
        fprintf(stderr, "ERROR on binding");
        exit(1);
    }

    if( listen(sockfd, 5) < 0)
    {
        printf("ERROR ON LISTEN");
        exit(1);
    }

    // accept
    clilen = sizeof(cli_addr);

    do{

        newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
        if(newsockfd < 0)
        {
            fprintf(stderr, "ERROR on accept\n");
            exit(1);
        }

        pid = fork();
        if(pid == 0)
        {
            bzero(buffer, 4096);
            n = read(newsockfd, buffer, 4095);

            if(n < 0)
            {//message from client
                fprintf(stderr, "ERROR Reading from socket\n");
                exit(1);
            }

            strcpy(hostname, buffer);
            printf("Here is the hostname: %s\n", &hostname[0]);

            //variables used for acsessing webserver?
            int sockwb, wbport, x;
            struct sockaddr_in webser_addr;
            struct hostent *wbhost;
            char webbuf[4096];//sending to webserver

            wbport = 80;//port used to access web server

            sockwb = socket(AF_INET, SOCK_STREAM, 0);

            if(sockwb < 0)
            {
                printf("Error opeing websocket\n");
                exit(1);
            }


        //    hostname_len = sizeof(hostname) / sizeof(hostname[0]);
        //    printf("%d\n", hostname_len);
        //    memcpy(host, hostname, hostname_len);
        //    host[hostname_len] = '\0';
            printf("%s\n", host);
        //    hostname[hostname_len] = '\0';

        //    host = &hostname[0];

            //wbhost = gethostbyname(hostname);
            wbhost = gethostbyname(host);
            //printf("%s", wbhost->h_name);

            printf("here2\n");

            /*if(wbhost == NULL)
            {
                printf("NO SUCH web HOST\n");
                exit(1);
            }
            */
            bzero((char*) &webser_addr, sizeof(webser_addr));

            webser_addr.sin_family = AF_INET;

            bcopy((char *)wbhost->h_addr, (char *)&webser_addr.sin_addr.s_addr, wbhost->h_length);

            webser_addr.sin_port = htons(wbport);

        //    printf("here3\n");

            if(connect(sockwb, (struct sockaddr *) &webser_addr,sizeof(webser_addr)) < 0)
            {
                printf("Error on web connecting\n");
                exit(1);
            }

            bzero(webbuf, 4096);
            strcpy(webbuf, "GET / HTTP/1.0\r\nHost: ");
        //    strcat(webbuf, hostname);
            strcat(webbuf, host);
            strcat(webbuf, "\r\nConnection: close\r\n\r\n");


        //    const char * request = "GET / HTTP/1.0\r\nHost: example.com\r\nConnection: close\r\n\r\n";

        //    printf("%s\n", request);
        //    x = write(sockwb, request, strlen(request));

            printf("%s\n", webbuf);
            x = write(sockwb, webbuf, strlen(webbuf));

            if(x < 0)
            {
                printf("Error writing to web sock");
                exit(1);
            }

            bzero(webbuf, 4096);
            x = read(sockwb, webbuf, 4096);

            if(n < 0)
            {
                printf("Error reading from web socket");
                exit(1);
            }

            printf("%d\n", (int)strlen(webbuf));
            printf("%s\n",webbuf);

            n = write(newsockfd, webbuf, 4095 );//write back to client

            if(n < 0)
            {
               fprintf(stderr, "ERROR WRITING to socket");
               exit(1);
            }

            //printf("%s\n", webbuf);
        }//end of if pid==0

        printf("closing client");
        close(newsockfd);//closing client socket


    }while(1);

    return 0;
}

最佳答案

您发布的代码运行畅通无阻。当您寻求帮助时,您应该始终发布 complete, verifiable例子。检查您发布的代码是否确实重现了问题!

看看代码的作用,似乎在服务器中,您打算使用您读取的主机名作为 gethostbyname 的参数。你可以这样做

host = &hostname[0];

或更简单

host = hostname;

或者首先不使用两个单独的变量。

当您在需要值的上下文中使用数组时(而不是例如获取其地址或其 sizeof),数组会衰减为指向其第一个元素的指针。所以这里的hostname相当于hostname[0]

更改后,仔细检查跟踪,或者,为了使问题更加明显,请将跟踪行更改为

            printf("[%s]\n", hostname);

你会看到

[aaa.com
]

客户端使用fgets读取一行,其中包括终止换行符。客户端尽职尽责地将整行转发到服务器。因此服务器查找包含换行符的主机名,但该字符不存在。您没有检查 gethostbyname 的返回代码(您应该!),它返回一个空指针,并且当程序尝试从中读取数据时会崩溃。

关于c - 如何将 char[ ] 转换为 char * ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35442520/

相关文章:

c - C 结构与 Fortran 的互操作

c - 使用 union 变量分配两个值

javascript - 如何使用 ES6 Array.fill() 清空数组

c - 如何在 C 中生成 "real"常量?

c - 如何使用 system() 将脚本的返回值返回给 c 程序

c - 为给定掩码生成所有位模式

python - 将 numpy 数组拆分为不重叠的数组

c++ - 类和数组

pointers - 在指针方法 Go 中初始化指针接收器

c - 如何释放二维数组?