簡體   English   中英

如何在C中查找所有出現的子字符串

[英]How to Find all occurrences of a Substring in C

我正在嘗試用 C 編寫一個解析程序,它將從 HTML 文檔中獲取某些文本段。 為此,我需要在文檔中找到子字符串“name”的每個實例; 但是,C 函數 strstr 只找到子字符串的第一個實例。 我找不到可以找到第一個實例以外的任何內容的函數,並且我已經考慮在找到每個子字符串后刪除它,以便 strstr 返回下一個。 我無法讓這兩種方法中的任何一種起作用。

順便說一下,我知道 while 循環將其限制為 6 次迭代,但我只是在測試這個,看看我是否可以讓函數首先工作。

while(entry_count < 6)
{   
    printf("test");
    if((ptr = strstr(buffer, "\"name\":")) != NULL)
    {   
        ptr += 8;
        int i = 0;
        while(*ptr != '\"')
        {   
            company_name[i] = *ptr;
            ptr++;
            i++;
        }   
        company_name[i] = '\n';
        int j;
        for(j = 0; company_name[j] != '\n'; j++)
            printf("%c", company_name[j]);
        printf("\n");
        strtok(buffer, "\"name\":");
        entry_count++;
    }   
}   

只需將返回的指針加一傳遞回strstr()即可找到下一個匹配項:

char *ptr = strstr(buffer, target);
while (ptr) {
    /* ... do something with ptr ... */
    ptr = strstr(ptr+1, target);
}

附言。 雖然您當然可以這樣做,但我建議您可能希望考慮更適合這項工作的工具:

  • C 是一種非常低級的語言,嘗試用它編寫字符串解析代碼很費力(特別是如果你堅持從頭開始編寫所有代碼,而不是使用現有的解析庫或解析器生成器)並且容易出錯(其中一些,像緩沖區溢出一樣,會產生安全漏洞)。 有很多被更好的適合這樣的任務,更高層次的腳本語言(如Perl和Ruby,Python或甚至和JavaScript)的。

  • 解析 HTML 時,您確實應該使用合適的 HTML 解析器(最好結合良好的 DOM 構建器和查詢工具)。 這將允許您根據文檔的結構定位所需的數據,而不僅僅是匹配原始 HTML 源代碼中的子字符串。 真正的 HTML 解析器還將透明地處理字符集轉換和字符實體解碼等問題。 的,有HTML解析器C,如濃湯喧嘩,所以即使你堅持堅持C.你可以和應該使用一個)

/*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *\
 *                                                  *
 *  SubStg with parameters in the execution line    *
 *  Must use 2 parameters                           *
 *  The 1st is the string to be searched            *
 *  The 2nd is the substring                        *
 *  e.g.:  ./Srch "this is the list" "is" >stuff    *
 *  e.g.:  ./Srch "$(<Srch.c)" "siz"                *
 *  (ref: http://1drv.ms/1PuVpzS)                   *
 *  © SJ Hersh 15-Jun-2020                          *
 *                                                  *
\*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char* char_ptr;
typedef unsigned int* int_ptr;
#define NOMEM ( int_ptr )0

int main( int parm, char** stgs )
{
   char_ptr string, substg;
   unsigned int sizstg, sizsub, endsiz, *ary;
   int_ptr startmem;
   register unsigned int x, y, ctr=0;

   if( parm != 3 )
   {
      printf( "ERR: You need exactly 2 string arguments\n" );
      return ( -8 );
   }

   string = stgs[ 1 ];
   substg = stgs[ 2 ];
   sizstg = strlen( string );
   sizsub = strlen( substg );
   endsiz = sizstg - sizsub + 1;


      /* Check boundary conditions: */

if( ( sizstg == 0 ) || ( sizsub == 0 ) )
{
   printf( "ERR: Neither string can be nul\n" );
   return( -6 );
}

if( sizsub > sizstg )
{
   printf( "ERR: Substring is larger than String\n" );
   return( -7 );
}

if( NOMEM == ( ary = startmem = malloc( endsiz * sizeof( int ) ) ) )
{
   printf( "ERR: Not enough memory\n" );
   return( -9 );
}


      /* Algorithm */

   printf( "Positions:\t" );

   for( x = 0; x < endsiz; x++ )
      *ary++ = string[ x ] == substg[ 0 ];

   for( y = 1, ary = startmem; y < sizsub; y++, ary = startmem )
      for( x = y; x < ( endsiz + y ); x++ )
         *ary++ &= string[ x ] == substg[ y ];

   for( x = 0; ( x < endsiz ); x++ )
      if( *ary++ )
      {
         printf( "%d\t", x );
         ctr++;
      }

   printf( "\nCount:\t%d\n", ctr );
   free( startmem );
   return( 0 );
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM