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

时间:2016-02-16 20:40:02

标签: 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);

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

任何想法都表示赞赏。

在客户端程序中,我使用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;
}

4 个答案:

答案 0 :(得分:2)

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

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

做到这一点
gethostbyname

或更简单

host = &hostname[0];

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

当您在需要值的上下文中使用数组时(而不是例如获取其地址或其host = hostname; ),数组会衰减为指向其第一个元素的指针。因此sizeof相当于hostname

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

hostname[0]

你会看到

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

客户端读取一行[aaa.com ] ,其中包含计数中的终止换行符。客户端尽职尽责地将整行转发给服务器。因此服务器查找包含换行符的主机名,该换行符不存在。你没有检查fgets的返回代码(你应该!),它会返回一个空指针,程序在尝试从中读取时会崩溃。

答案 1 :(得分:1)

@Gilles是对的,你在主机名的末尾有一个'\ n',下面的一段代码将'\ n'替换为0,这相当于字符'\ 0':

    extern int h_errno;
    ...
    hostname[strlen(hostname) - 1] = 0;
    wbhost = gethostbyname(hostname);

    if (!wbhost) {
      printf("Failed! %s\n", strerror(h_errno));
      exit(1);
    }
    ...

答案 2 :(得分:0)

char[]转换为char *的最简单方法可能是:

char example_array[] = "example";
char * example_pointer = (char *)calloc(1, strlen(example_array) + 1); // + 1 for the '\0' character
strcpy(example_pointer, example_array);

答案 3 :(得分:0)

char[]是一组字符。 char*是指向char的指针 - 通常(但不总是)字符串的开头。

如果你想获得指向数组开头的指针,你甚至不需要做任何事情!这种转换是隐含的:

char hello[6] = {'h', 'e', 'l', 'l', 'o', '\0'};
// or: char hello[] = "hello"; (equivalent to above)
printf("%s", hello); // prints hello
puts(hello); // also prints hello

char *hello2 = hello;
puts(hello2); // also prints hello