整理一下日常用到的c++中的字符串处理函数
1.strpbrk和strspn
最近看了一个解析http请求的方法,里面用到了这俩函数,在这里记录一下。首先,http的请求报文的格式如下:
strpbrk和strspn的原型和注释为:
/* Find the first occurrence in S of any character in ACCEPT. */
extern char *strpbrk (char *__s, const char *__accept)
__THROW __asm ("strpbrk") __attribute_pure__ __nonnull ((1, 2));
/* Return the length of the initial segment of S which
consists entirely of characters in ACCEPT.
该函数返回 s 中第一个不在字符串 accept 中出现的字符下标。 */
extern size_t strspn (const char *__s, const char *__accept)
__THROW __attribute_pure__ __nonnull ((1, 2));
结合实例进行说明,现在假设报文如下:
现在结合代码和上面示例进行解析:
http_conn::HTTP_CODE http_conn::parse_request_line(char *text)
{
m_url = strpbrk(text, " t");
//m_url=t/chapter17/user.html HTTP/1.1
if (!m_url)
{
return BAD_REQUEST;
}
*m_url++ = '0';
//将t替换为0 m_url=/chapter17/...
char *method = text;
//应为有0的存在,method=POST
if (strcasecmp(method, "GET") == 0)
m_method = GET;
else if (strcasecmp(method, "POST") == 0)
{
m_method = POST;
cgi = 1;
}
else
return BAD_REQUEST;
m_url += strspn(m_url, " t");
//确保第一个不是空格 m_url=/chapter17/...
m_version = strpbrk(m_url, " t");
//m_version=tHTTP/1.1
if (!m_version)
return BAD_REQUEST;
*m_version++ = '0';
//将t替换为0 m_version=HTTP1.1
m_version += strspn(m_version, " t");
if (strcasecmp(m_version, "HTTP/1.1") != 0)
return BAD_REQUEST;
if (strncasecmp(m_url, "http://", 7) == 0)
{
m_url += 7;
m_url = strchr(m_url, '/');
}
if (strncasecmp(m_url, "https://", 8) == 0)
{
m_url += 8;
m_url = strchr(m_url, '/');
}
if (!m_url || m_url[0] != '/')
return BAD_REQUEST;
//当url为/时,显示判断界面
if (strlen(m_url) == 1)
strcat(m_url, "judge.html");
m_check_state = CHECK_STATE_HEADER;
return NO_REQUEST;
}
2.strcpy
char *strcpy(char *strDest,const char *strSrc);
微软中的此函数的参数说明:
/***
*char *strcpy(dst, src) - copy one string over another
*
*Purpose:
* Copies the string src into the spot specified by
* dest; assumes enough room.
*
*Entry:
* char * dst - string over which "src" is to be copied
* const char * src - string to be copied over "dst"
*
*Exit:
* The address of "dst"
*
*Exceptions:
*******************************************************************************/
有时笔试中会让手写一下strcpy的代码,并问一下为什么会返回char*?
char * __cdecl strcpy(char * dst, const char * src)
{
char * cp = dst;
while( *cp++ = *src++ )
; /* Copy src over dst */
return( dst );//这块要注意一下返回dst,而不是cp,因为cp是栈上的变量,如果强行返回,
//会导致输出为乱码
}
大部分人可能看到为什么会返回char*,会想到的是越界的问题,在strcpy是假设dst有足够空间的。如果src的长度>dst的长度,也可以拷贝过去,但在最后程序会报
Stack around the variable 'dst' was corrupted.
至于为什么这么做?
通过这篇博客的博主,我了解到了是为了获得灵活性。例如:
char str[20];
int length = strlen( strcpy(str, “Hello World”) );
至此,解释完毕,后续再补充其他字符串的处理函数。