首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C在字符串中获取字符串的一部分

C在字符串中获取字符串的一部分
EN

Stack Overflow用户
提问于 2014-12-04 19:05:16
回答 4查看 167关注 0票数 4

我试图编写解析HTTP请求并检查“主机”是否为www.bbc.co.uk的代码。

这是我的工作代码:

代码语言:javascript
复制
char data[] = "GET /news/ HTTP/1.1\nHost: www.bbc.co.uk\nConnection: keep-alive";
    unsigned int size = strlen(data);

    if (size>3 && data[0] == 'G' && data[1] == 'E' && data[2] == 'T'){ //If GET Request
        int host_index = -1;

        for (int i=4; i<size-4; i++){
            if (data[i] == 'H' && data[i+1] == 'o' && data[i+2] == 's' && data[i+3] == 't'
                    && data[i+4] == ':' && data[i+5] == ' '){
                host_index = i+6;
            }
        }

        if ( host_index != -1 && size > host_index+11 &&
                data[host_index] == 'w' && data[host_index+1] == 'w' && data[host_index+2] == 'w' &&
                data[host_index+3] == '.' && data[host_index+4] == 'b' && data[host_index+5] == 'b' &&
                data[host_index+6] == 'c' && data[host_index+7] == '.' && data[host_index+8] == 'c' &&
                data[host_index+9] == 'o' && data[host_index+10] == '.' && data[host_index+11] == 'u' &&
                data[host_index+12] == 'k')
        {
            printf("BBC WEBSITE!\n");
        }

    }

我认为这是很多代码,不是很多。如何使这段代码更紧凑?

请把它保持在普通C上,不要用第三方语言。

非常感谢!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-12-04 19:18:52

您的代码可以编写得更简洁,如下所示:

代码语言:javascript
复制
   if (!strncmp(data, "GET ", 4) && strstr(data, "\nHost: www.bbc.co.uk\n"))
       printf("BBC WEBSITE!\n");

然而,虽然这可能在99.9%的情况下工作,但它不处理冒号后的任意空白。正则表达式会很有帮助,但是这需要一个第三方库,这是您无法拥有的。

一个解决办法是:

代码语言:javascript
复制
  if (!strncmp(data, "GET ", 4)) {
      const char *p = data;
      char buf[99 + 1];
      buf[0] = 0;
      while ((p = strchr(p, '\n')) && sscanf(++p, "Host: %99s", buf) != 1)
          ;
      if (!strcmp(buf, "www.bbc.co.uk"))
          printf("BBC WEBSITE!\n");
  }

编辑:上面的解决方案允许在"Host:"之后使用任意数量的CRs和/或LFs。我不清楚HTTP/1.1 LWS (线性空白)是否允许这样做。如果不允许,并且只允许零或多个空格和制表符,请将sscanf更改为:

代码语言:javascript
复制
   (sscanf(++p, "Host:%*[ \t]%99[^ \t]", buf) == 1 || 
    sscanf(p,   "Host:%99[^ \t]",        buf) == 1)

正如你所看到的,它开始变得凌乱。

票数 2
EN

Stack Overflow用户

发布于 2014-12-04 19:09:26

为什么不使用strstr()呢?

使用strstr()将大字符串拆分为块,然后通过不同的例程解析较小的块

票数 4
EN

Stack Overflow用户

发布于 2014-12-04 19:16:53

仅使用标准库函数,您可以:

代码语言:javascript
复制
char data[] = 
    "GET /news/ HTTP/1.1\n"
    "Host: www.bbc.co.uk\n"
    "Connection: keep-alive";

char *found_host = strstr(data, "Host: ");

if (found_host != NULL) {
    found_host += sizeof("Host: ") - 1;

    char *end_of_host = strpbrk(found_host, "\r\n");

    if (end_of_host != NULL) {
        int equal = strncmp(found_host, "www.bbc.co.uk", end_of_host - found_host);
    }
}

请注意,这并不说明冒号和值之间存在任意数量的空白。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27301956

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档