我有以下字符串:
GET /index.html HTTP/1.0;;User-Agent: Wget/1.11.4;;Accept: */*;;Host: www.google.com;;Connection
我使用以下代码来解析每个元素:
while (parser != NULL){
printf ("%s\n",parser);
parser = strtok (NULL, ";;");
}
输出:
GET /index.html HTTP/1.0
User-Agent: Wget/1.11.4
Accept: */*
Host: www.google.com
Connection
现在我只需要获取主机网址,在这种情况下是www.google.com。所以首先我想把它与其他东西分开。
为此,我将另一个解析器放在我的前一个解析器中,如下所示:
while (parser != NULL){
char * pars = strtok (string,":");
while (pars != NULL) {
printf("%s\n", pars);
pars = strtok (NULL, ":");
}
parser = strtok (NULL, ";;");
}
这是一些混乱的东西。我不明白为什么......谁能看到错误?感谢
答案 0 :(得分:4)
您的代码无效的原因是strtok
不可重入。因为该函数使用静态变量来保存状态(这是让strtok
调用NULL
作为第一个参数的原因)你不能在嵌套循环中设置strtok
的调用:一旦你告诉strtok
使用":"
分隔符进行解析,它会“忘记”使用";"
分隔符进行解析的状态。
切换到strtok
- strtok_r
的可重入版本,可以解决此问题。此功能要求您提供额外参数savePtr
。重要提示:您需要为内部和外部循环中的savePtr
strtok_r
提供两个不同的变量,否则代码将表现出相同的行为。
注意:strtok_r
不是C标准的一部分。但是,大多数流行的C库都可以使用它。如果您的库没有strtok_r
,请找到它的源代码,并将其添加到您自己的代码库中。
答案 1 :(得分:0)
您的方法存在一个大问题 - 除了strtok
不可重入的问题。这就是strtok
查找“与任何令牌匹配” - 因此strtok(NULL, ";;")
将停在第一个;
,而不是第一个;;
。
我会采用不同的方式 - 你正在寻找一个特定的字符串("\nHost: "
) - 搜索它,然后找到下面的位。这似乎是一个更强大的解决方案。
另请注意strtok
修改了它的参数 - 基本上它会在找到令牌的地方添加'\0'
,因此在{{1}操作后,您将无法重新使用该字符串。 }}。如果您想在之后使用该字符串,则需要先制作副本。
所有这些都表明你想重新思考你的解析策略。 <怎么样
char * inputString =“GET /index.html HTTP / 1.0 ;; User-Agent:Wget / 1.11.4 ;;接受: / ;;主持人:www.google.com ;;连接”; char * temp,* hostString,* endHost; temp = strstr(inputString,“;; Host:”)+ 7; //点击“主持人:”之后 endHost = strstr(temp,“;;”); nChar =(int)(endHost - temp)+ 1; hostString = malloc(nChar); strcpy(hostString,temp,nChar);
这只是为了查找/提取主机字符串。