将字符串中的 n 个字符传递给 C 中的函数
Pass n characters from string to function in C
我正在测试 URL 是否包含某些扩展名。我必须这样做大约 100M 次。我试图在没有查询字符串的情况下传递 URL,因此我可以将 URL 的最后 3 个字符与某些条件进行比较。
我的问题是,我可以只将 http://www.e.com/msusa/DisplayContactPage.jsp
传递给 textExtension
吗?没有在 main 中修改 url
并且没有 strdup
字符串?
int testExtension(char *url) {
// compare last 3 chars against possible extensions
// return 0 if matches extension, else return 1
return match ? 0 : 1;
}
int main () {
char *url = "http://www.e.com/msusa/DisplayContactPage.jsp?q=string&t=12"
testExtension(url);
}
我当然可以:
if ((end=strchr(url, '?')))
*end=0;
但这会修改 url
您可以采取的步骤:
在URL中找到'?'
。
char* cp = strchr(url, '?');
找到后,将指针向后移动三位。如果没找到,就把它移到字符串末尾前3个字符。
检查前一个字符是否为 '.'
。这是扩展名的开始。将指针传递给 textExtension
.
if ( cp == NULL )
{
len = strlen(url);
cp = url + (len-3);
}
cp -= 3;
if ( *(cp-1) != '.' )
{
// Deal with the condition.
}
// Call textExtension.
testExtension(cp);
确保您不访问 '?'
以外的任何内容或 testExtension
中的空字符。
如果您不确定扩展名中的字符数,您可以使用:
char* cp = strchr(url, '?');
if ( cp == NULL )
{
len = strlen(url);
cp = url + len;
}
// Move the pointer back until you find the '.'
while ( *cp != '.' && cp > url )
{
--cp;
}
有几种方法可以解决这个问题。
方案一:对子串进行操作
static const int EXTENSION_LEN = 3;
int testExtension(const char *url) {
int pos = index(url, '?');
if (pos > EXTENSION_LEN) {
pos -= EXTENSION_LEN;
return (0 == strncmp(EXTENSION, (url + pos), EXTENSION_LEN));
}
else {
return 0;
}
}
根据您测试相同 URL 的次数,该 index() 操作的开销(与基数 URL 的长度成线性关系)可能会变得很大。您可以通过创建扩展的副本来避免它(请注意,您不需要整个 strdup() URL,而只需复制扩展)。
选项 2:将子字符串复制到新缓冲区
int testExtension(const char *extension) {
return (0 == strncmp(EXTENSION, extension, EXTENSION_LEN));
}
int main() {
char ext[EXTENSION_LEN];
char *url = "http://www.e.com/msusa/DisplayContactPage.jsp?q=string&t=12";
int testResult = 0;
int pos = index(url, '?');
if ( pos > EXTENSION_LEN ) {
for ( int idx = 0; idx < EXTENSION_LEN; ++idx ) {
ext[idx] = url[pos - EXTENSION_LEN + idx];
}
ext[EXTENSION_LEN - 1] = 0; // null-terminate
testResult = testExtension(ext);
}
}
如果您有很多扩展要测试,则可能需要散列 table 或其他数据结构才能获得不错的性能。
我正在测试 URL 是否包含某些扩展名。我必须这样做大约 100M 次。我试图在没有查询字符串的情况下传递 URL,因此我可以将 URL 的最后 3 个字符与某些条件进行比较。
我的问题是,我可以只将 http://www.e.com/msusa/DisplayContactPage.jsp
传递给 textExtension
吗?没有在 main 中修改 url
并且没有 strdup
字符串?
int testExtension(char *url) {
// compare last 3 chars against possible extensions
// return 0 if matches extension, else return 1
return match ? 0 : 1;
}
int main () {
char *url = "http://www.e.com/msusa/DisplayContactPage.jsp?q=string&t=12"
testExtension(url);
}
我当然可以:
if ((end=strchr(url, '?')))
*end=0;
但这会修改 url
您可以采取的步骤:
在URL中找到
'?'
。char* cp = strchr(url, '?');
找到后,将指针向后移动三位。如果没找到,就把它移到字符串末尾前3个字符。
检查前一个字符是否为
'.'
。这是扩展名的开始。将指针传递给textExtension
.if ( cp == NULL ) { len = strlen(url); cp = url + (len-3); } cp -= 3; if ( *(cp-1) != '.' ) { // Deal with the condition. } // Call textExtension. testExtension(cp);
确保您不访问
'?'
以外的任何内容或testExtension
中的空字符。
如果您不确定扩展名中的字符数,您可以使用:
char* cp = strchr(url, '?');
if ( cp == NULL )
{
len = strlen(url);
cp = url + len;
}
// Move the pointer back until you find the '.'
while ( *cp != '.' && cp > url )
{
--cp;
}
有几种方法可以解决这个问题。
方案一:对子串进行操作
static const int EXTENSION_LEN = 3;
int testExtension(const char *url) {
int pos = index(url, '?');
if (pos > EXTENSION_LEN) {
pos -= EXTENSION_LEN;
return (0 == strncmp(EXTENSION, (url + pos), EXTENSION_LEN));
}
else {
return 0;
}
}
根据您测试相同 URL 的次数,该 index() 操作的开销(与基数 URL 的长度成线性关系)可能会变得很大。您可以通过创建扩展的副本来避免它(请注意,您不需要整个 strdup() URL,而只需复制扩展)。
选项 2:将子字符串复制到新缓冲区
int testExtension(const char *extension) {
return (0 == strncmp(EXTENSION, extension, EXTENSION_LEN));
}
int main() {
char ext[EXTENSION_LEN];
char *url = "http://www.e.com/msusa/DisplayContactPage.jsp?q=string&t=12";
int testResult = 0;
int pos = index(url, '?');
if ( pos > EXTENSION_LEN ) {
for ( int idx = 0; idx < EXTENSION_LEN; ++idx ) {
ext[idx] = url[pos - EXTENSION_LEN + idx];
}
ext[EXTENSION_LEN - 1] = 0; // null-terminate
testResult = testExtension(ext);
}
}
如果您有很多扩展要测试,则可能需要散列 table 或其他数据结构才能获得不错的性能。