【问题标题】:Parse the HTTP String解析 HTTP 字符串
【发布时间】:2016-08-07 21:06:49
【问题描述】:

我如何解析这个字符串GET /STA/ID=HelloWorld/Pass=Testin123 HTTP/1.1首先我需要检查STA,如果存在,继续扫描字符串。将ID 的值在这种情况下HelloWorld 应该存储在char 数据类型SSIDPass 的值中,在这种情况下Testin123 应该存储在char 数据类型Pass

它应该首先确认字符串中STA 的存在。如果不存在,则不要进入循环。如果退出,请搜索 IDPass。存储它。

现在的问题是我无法存储 IDpass 的值。也无法搜索STA

char GetString[] = "GET /STA/ID=Test/Pass=123 HTTP/1.1";

char *get = strtok(GetString, " ");
char *request = strtok(NULL, " ");
char *rtype = strtok(NULL, " ");
char *FirstPart;

int main()
{
 if (request != NULL)
 {
  FirstPart = strtok(request,"/");
  while(FirstPart)
   {
   if (!strncmp(part, "STA"))
       {
         //Print STA Found

          if(!strncmp(part, "ID=", 3))
             {
              //Store value of ID
             }

           if(!strncmp(part, "Pass=", 5))
             {
             //Store the Pass
             }
          }
       }
       FirstPart =strtok(NULL,'/');
   }
 } 

【问题讨论】:

  • 这是一个奇怪的地方停下来,你得到了正确的标记,但没有用 strcmp 测试字符串是否相等?
  • @covener 我已经添加了完整的代码。
  • 问题是小错误隐藏了你的大错误。对 strncmp 的调用无效,没有长度参数。使用第二个字符参数对 strtok 进行了无效调用,该参数应该是一个字符串。您的 while 循环正在遍历令牌,但仅当该令牌是“STA”时才执行任何操作,但如果是,则检查它是否是其他东西,但您知道它是“STA”,因此其他 if 子句永远无法匹配.
  • 这是一个学校项目吗?如果是,请忽略我的评论。 strtok 不是线程安全的。如果您正在运行并发 Web 服务器,您可能会遇到难以通过这种方式调试问题。我会尽可能避免使用这些功能。我也会考虑为此使用现有的库,编写糟糕的自定义解析器的成本可能高于事后审查完全解析的 HTTP 请求的成本。
  • @Myst 不,这不是学校项目。我需要可靠的解析字符串的方法。图书馆的任何链接都会有很大帮助!

标签: c string http parsing get


【解决方案1】:

需要进行一些清理。一个提示:使用编译器打开所有警告和错误,它们的存在是有原因的。您的代码甚至没有编译,这是这里的最低条件。

不过:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
  char GetString[] = "GET /STA/ID=Test/Pass=123 HTTP/1.1";
  // you cannot do it globally in that way, so I pulled it all into main()
  char *request, *FirstPart;
  // please don't use all upper-case for normal variables
  // I did it for some clarity here
  char *ID, *PASS;

  // skip "GET"
  strtok(GetString, " ");
  // get first part
  request = strtok(NULL, " ");

  if (request != NULL) {
    FirstPart = strtok(request, "/");
    // check for base condition
    if (!strncmp(FirstPart, "STA", 3)) {
      //Print STA Found
      printf("STA = %s\n", FirstPart);
    } else {
      fprintf(stderr, "STA not found!\n");
      exit(EXIT_FAILURE);
    }
    FirstPart = strtok(NULL, "/");
    // graze the key-value combinations
    while (FirstPart) {
      // We check them all here, one after the other
      if (!strncmp(FirstPart, "ID=", 3)) {
    //Store value of ID
    ID = strchr(FirstPart, '=');
    // ID is now "=Test", so skip '='
    ID++;
    printf("ID = %s, value of ID = %s\n", FirstPart, ID);
      } else if (!strncmp(FirstPart, "Pass=", 5)) {
    //Store the Pass
    PASS = strchr(FirstPart, '=');
    // PASS is now "=123", so skip '='
    PASS++;
    printf("PASS = %s, value of PASS = %s\n", FirstPart, PASS);
      } else {
    printf("Unknown part \"%s\", ignoring\n", FirstPart);
      }
      FirstPart = strtok(NULL, "/");
    }
  } else {
    fprintf(stderr, "No input at all\n");
    exit(EXIT_FAILURE);
  }
  exit(EXIT_SUCCESS);
}

指针IDPASS 仅指向以空值结尾的值,它们不是独立内存。您可以使用malloc() 获取一些并使用strlen() 测量数量。以ID为例:ptr_to_mem_for_ID = malloc(strlen(ID));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-03
    • 2010-10-29
    • 2013-08-02
    • 2019-11-07
    • 1970-01-01
    • 2014-01-01
    相关资源
    最近更新 更多