我有一个 char* 包含以下消息。“movie.mjpeg”名称的长度可变。如何分析 char*,以便将电影名称和 CSeq 编号保存在另一个变量中,然后丢弃 char*。
SETUP movie.Mjpeg RTSP/1.0 CSeq:1 传输:RTP/TCP;交错=0
您可以对字符串进行标记以提取特定字段,例如:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char inpStr[] = "SETUP movie.Mjpeg RTSP/1.0 CSeq: 1"
" Transport: RTP/TCP; interleaved=0";
int main (void) {
char *name, *cseq;
strtok (inpStr, " "); // SETUP
name = strdup (strtok (NULL, " ")); // movie.Mjpeg
strtok (NULL, " "); // RTSP/1.0
strtok (NULL, " "); // CSeq:
cseq = strdup (strtok (NULL, " ")); // 1
printf ("Name is [%s], cseq is [%s]\n", name, cseq);
free (name);
free (cseq);
return 0;
}
这个的输出是:
Name is [movie.Mjpeg], cseq is [1]
基本上,每次调用strtok
都会为您提供下一个标记的地址,并适当分隔。strdup
对(a)的调用将确保您获得字符串的副本,而不是指向原始字符串的指针。使用指向原始字符串的指针意味着对一个字符串的更改会影响另一个。
请记住,这会更改原始字符串,因此,如果您不希望这样做,请确保使用副本。
(a)标准 C 没有提供strdup
,尽管它在许多实现中都可用。如果您的实现没有,请参见此处。
假设静态字段确实是静态的,您可以使用它sscanf()
来扫描出可变部分。
这样做的好处(?)不依赖于strtok()
哪个是可怕的函数(它修改了输入字符串)。它还可以让您在同一操作中转换非字符串数据,这很方便。
const char *inpStr = "SETUP movie.Mjpeg RTSP/1.0 CSeq: 1 Transport: RTP/TCP; interleaved=0";
char filename[128], transport[32];
int cseq;
if(sscanf(inpStr, "SETUP %s RTSP/1.0 CSeq: %d Transport: %s;",
filename, &cseq, transport) == 3)
{
printf("Got filename '%s', cseq=%d, transport='%s'\n",
filename, cseq, transport);
}
请注意,检查的返回值sscanf()
以确保它确实成功地转换了所有字段是一个好主意,否则您不能依赖存在的值。