【问题标题】:Pass n characters from string to function in C将字符串中的 n 个字符传递给 C 中的函数
【发布时间】:2015-09-01 03:11:28
【问题描述】:

我正在测试一个 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;

但这会修改​​网址

【问题讨论】:

    标签: c string pointers pointer-arithmetic


    【解决方案1】:

    您可以采取的步骤:

    1. 在网址中找到'?'

      char* cp = strchr(url, '?');
      
    2. 如果找到它,请将指针向后移动三倍。如果找不到,请将其移至字符串末尾前 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);
      
    3. 确保您不访问除'?'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;
    }
    

    【讨论】:

      【解决方案2】:

      有几种方法可以解决这个问题。

      选项1:对子字符串进行操作

      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);
          }
      }
      

      如果您有很多扩展要测试,那么可能需要哈希表或其他数据结构来获得不错的性能。

      【讨论】:

        猜你喜欢
        • 2013-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-16
        • 1970-01-01
        • 1970-01-01
        • 2015-09-09
        • 1970-01-01
        相关资源
        最近更新 更多