如何在C

时间:2015-04-25 14:43:34

标签: html c algorithm parsing

我正在尝试在C中编写一个解析程序,它将从HTML文档中获取某些文本段。为此,我需要在文档中找到子字符串" name":的每个实例;但是,C函数strstr只查找子字符串的第一个实例。我找不到一个超出第一个实例的函数的函数,并且我已经考虑在找到它之后删除每个子字符串,以便strstr返回下一个。我无法使用这两种方法。

顺便说一句,我知道while循环将此限制为六次迭代,但我只是测试它,看看我是否可以让函数首先工作。

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

2 个答案:

答案 0 :(得分:4)

只需将返回的指针加一,返回strstr()即可找到下一个匹配项:

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

Ps。虽然您当然可以这样做,但我建议您不妨考虑使用更合适的工具:

  • C是一种非常低级的语言,并且尝试在其中编写字符串解析代码是很费力的(特别是如果你坚持从头开始编写所有内容,而不是使用现有的解析库或解析器生成器)并且容易错误(其中一些,如缓冲区溢出,可能会产生安全漏洞)。有许多更高级别的脚本语言(如Perl,Ruby,Python甚至JavaScript),很多更适合这样的任务。

  • 解析HTML时,你真的应该使用一个合适的HTML解析器(最好结合一个好的DOM构建器和查询工具)。这将允许您根据文档的结构找到所需的数据,而不是仅匹配原始HTML源代码中的子字符串。真正的HTML解析器还将透明地处理字符集转换和字符实体解码等问题。 (是的, C的HTML解析器,例如GumboHubbub,所以即使你坚持坚持C,你也可以并且应该使用它。)

答案 1 :(得分:0)

/*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *\
 *                                                  *
 *  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 );
}