2016-02-28 125 views
7

我的代碼有問題,我需要你的幫助!我需要做的是編寫一個函數,該函數將從輸入的字符串中提取從www.開始並以.edu開頭的網址。輸入的字符串中沒有空格,所以scanf()應該在這裏工作。從C中的一個字符串中提取網址地址

例如:
http://www.school.edu/admission。提取的地址應該是www.school.edu

這是我到目前爲止所做的,顯然沒有奏效,我不能想到其他任何事情。

void extract(char *s1, char *s2) { 
    int size = 0; 
    char *p, *j; 

    p = s1; 
    j = s2; 
    size = strlen(s1); 

    for(p = s1; p < (s1 + size); p++) { 
     if(*p == 'w' && *(p+1) == 'w' && *(p+2) == 'w' && *(p+3) == '.'){ 
      for(p; p < (p+4); p++) 
       strcat(*j, *p); 
     } 
     else if(*p=='.' && *(p+1)=='e' && *(p+2)=='d' && *(p+3)=='u'){ 
      for(p; (p+1) < (p+4); p++) 
       strcat(*j, *p);      
     } 
    } 
    size = strlen(j); 
    *(j+size+1) = '\0'; 
} 

該函數具有使用指針運算。我得到的錯誤與不兼容的類型和轉換有關。謝謝!

+2

請在問題中包含**全**錯誤消息。這對我們有很大的幫助。 –

+0

將'char'數據傳遞給'strcat()'不是一個好主意。 – MikeCAT

+2

'p <(p + 4)'和'(p + 1)<(p + 4)'總是如此。 – MikeCAT

回答

1

所以最微不足道的方法可能是:

#include <stdio.h> 

int main(void) 
{ 
    char str[1000]; 
    sscanf("http://www.school.edu/admission", "%*[^/]%*c%*c%[^/]", str); 
    puts(str); 
} 

現在,在這裏不用固定代碼:

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

void extract(char *s1, char *s2) { 
    size_t size = strlen(s1), i = 0; 
    while(memcmp(s1 + i, "www.", 4)){ 
     i++; 
    } 
    while(memcmp(s1 + i, ".edu", 4)){ 
     *s2++ = *(s1 + i); 
     i++; 
    } 
    *s2 = '\0'; 
    strcat(s2, ".edu"); 
} 

int main(void) 
{ 
    char str1[1000] = "http://www.school.edu/admission", str2[1000]; 
    extract(str1, str2); 
    puts(str2); 
} 

請注意,s2必須足夠大以包含提取的網址,否則您可能會收到段錯誤。

-1

不幸的是有很多錯誤。你的編譯失敗了,因爲你在需要char *時將字符傳遞給strcat。即使它編譯了,但它會崩潰。

for(p = s1; p < (s1 + size); p++) { 
    // This if statement will reference beyond s1+size when p=s1+size-2. Consequently it may segfault 
    if(*p=='w' && *(p+1)=='w' && *(p+2)=='w' && *(p+3)=='.') { 
     for(p; p < (p+4); p++) // This is an infinite loop 
      // strcat concatenates one string onto another. 
      // Dereferencing the pointer makes no sense. 
      // This is the likely causing your compilation error. 
      // If this compiled it would almost certainly segfault. 
      strcat(*j, *p); 
    } 
    // This will also reference beyond s1+size. Consequently it may segfault 
    else if(*p=='.' && *(p+1)=='e' && *(p+2)=='d' && *(p+3)=='u') { 
     for(p; (p+1) < (p+4); p++) // This is also an infinite loop 
      // Again strcat expects 2x char* (aka. strings) not 2x char 
      // This will also almost certainly segfault. 
      strcat(*j, *p); 
    } 
} 

// strlen() counts the number of chars until the first '\0' occurrence 
// It is never correct to call strlen() to determine where to add a '\0' string termination character. 
// If the character were actually absent this would almost certainly result in a segfault. 
// As it is strcat() (when called correctly) will add the terminator anyway. 
size = strlen(j); 
*(j+size+1) = '\0'; 

編輯:這似乎是一個家庭作業的問題,所以我認爲這將是更有建設性的提在您當前的代碼是哪裏錯了,這樣你就可以在這些地區重新檢查你的知識。

您的確切問題的答案是它不會編譯,因爲您取消引用字符串,因此將char *而不是char *傳遞給strcat()。

+0

'if'語句沒有未定義的行爲,因爲運算符'&&'應用了短路評估。由於該操作符從左到右進行評估,因此評估僅停留在NUL字符處。根據這個問題,人們還可以安全地假設這兩個子字符串都包含在字符串中。 –

0

這是你的問題的一個簡單的解決方案:

char* extract(char *s1) { 
char* ptr_www; 
char* ptr_edu; 
int len ; 
char* s2; 

ptr_www = strstr(s1,"www"); 
ptr_edu = strstr(s1,".edu"); 

len = ptr_edu -ptr_www + 4; 

s2 = malloc (sizeof(char)*len+1); 
strncpy(s2,ptr_www,len); 
s2[len] = '\0'; 
printf ("%s",s2); 

return s2; 
} 
+0

但是,如果「www」或「.edu」或兩者都不在字符串「s1」內呢? –

+0

是的,我們可以添加一些條件來處理這個問題,但我相信提問者認爲地址應該包含「www」和「.edu」 – fedi

+0

是的,沒錯。我忽略了它。提問者甚至在「www」之後使用'.'。我建議添加一些你的代碼的解釋。 –