Как разобрать URL-адреса в C с помощью sscanf ()? - PullRequest
3 голосов
/ 25 января 2010

Это мой код C, который читает список URL-адресов из файла и пытается отделить различные части URL-адреса. Это просто грубый разбор, меня не беспокоят особые случаи. Я предполагаю, что есть какая-то ошибка с оператором sscanf (); когда я запускаю это, я получаю «НЕИСПРАВНОСТЬ сегментации». И более того, полный URL-адрес присваивается строке «proto».

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

# define BAG_SIZE 14

char bag[117][30];

void initbag()
{
strcpy(bag[0],"account");
strcpy(bag[1],"audit");
strcpy(bag[2],"ad");
strcpy(bag[3],"advertising");
strcpy(bag[4],"marketing");
strcpy(bag[5],"application");
strcpy(bag[6],"banking");
strcpy(bag[7],"barter");
strcpy(bag[8],"business");
strcpy(bag[9],"econo");
strcpy(bag[10],"commerce");
strcpy(bag[11],"communication");
strcpy(bag[12],"computer");
strcpy(bag[13],"processing");
}
/*
 other bag[] values will be later copied
*/

void substr(char dest[10],char src[200],int start,int len)
{
int i,j;

for(i=start,j=0;i<start+len;i++,j++)
dest[j]=src[i];
dest[j]='\0';

}

int found(char* word)
{
   int i;
   for(i=0;i<BAG_SIZE;i++)
   if((!strcmp(word,bag[i]))||(strstr(bag[i],word)!=NULL)) return 1;
   return 0;
}

void main()
{
int i,j,k;

char buff[10],fullurl[100];
char proto[5],www[4],host[100],tokens[200],tld[4];
float feature[11];for(i=0;i<11;i++) feature[i]=0;
FILE *furl,*fop;
furl=fopen("bizurls.txt","r");
fop=fopen("urlsvm.txt","w");
initbag();
printf("\nbag initialised");fflush(stdout);

while(!feof(furl))
{
   fscanf(furl,"%s",fullurl);
   printf("%s",fullurl);
   sscanf(fullurl,"%s://%s.%s.%s/%s\n",proto,www,host,tld,tokens);// this line isnt working properly
   printf("2hi");fflush(stdout);
   printf("proto : %s\nwww:%s\nhost :%s\ntld:%s\ntokens:%s\n",proto,www,host,tld,tokens);fflush(stdout);


   for( i=4;i<=8;i++)
   {
       for(j=0;j<strlen(host)-i+1;j++)
           {
                substr(buff,host,j,i);
                if(found(buff)) feature[i-3]++;

           }
   }
  if((!strcmp(tld,"biz"))||(!strcmp(tld,"org"))||(!strcmp(tld,"com"))||(!strcmp(tld,"jobs")))   
        feature[0]=1;
  else if((!strcmp(tld,"info"))||(!strcmp(tld,"coop"))||(!strcmp(tld,"net")))
        feature[0]=0.5;
  else
    feature[0]=0;


   for( i=4;i<=8;i++)
   {
       for(j=0;j<strlen(tokens)-i+1;j++)
           {
                substr(buff,tokens,j,i);
                if(found(buff)) feature[i+2]++;

           }
   }

/*.biz · .com · .info · .name · .net · .org · .pro
.aero, .coop, .jobs, .travel */

for(i=0;i<11;i++) fprintf(fop," %d:%f",i,feature[i]);
fprintf(fop,"\n");


}
fflush(fop);
fclose(furl);
fclose(fop);
}

Ответы [ 3 ]

3 голосов
/ 25 января 2010

% s в sscanf остановится только тогда, когда попадет первый пробел, конец строки или указанная максимальная длина. Видя, что URL не имеет пробелов, вот почему прото становится fullurl.

Для ошибки сегментации: поскольку proto может содержать только 5 байтов (включая завершающий ноль, поэтому только 4 байта данных, которые не будут охватывать, например, https), размещение полного URL-адреса в нем вызовет ошибку переполнения / сегментации буфера. sscanf довольно проблематичен в этом отношении. Документация требует, чтобы каждый буфер символов, получающий% s, был достаточно большим, чтобы вместить полную строку (плюс \ 0).

2 голосов
/ 25 января 2010
1 голос
/ 25 января 2010

Это не будет работать, потому что proto будет соответствовать целому fullurl, а остальные не будут сопоставлены. Для этого вы должны использовать правильную функцию парсинга URL или регулярное выражение.

...