【问题标题】:Extracting web addresses from a string in C从C中的字符串中提取网址
【发布时间】:2016-02-28 07:03:35
【问题描述】:

我的代码有问题,需要您的帮助!我需要做的是编写一个函数,该函数将从输入的字符串中提取以www. 开头并以.edu 结尾的网址。输入的字符串中没有空格,所以scanf() 应该可以在这里正常工作。

例如:
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';
}

函数必须使用指针运算。我得到的错误与不兼容的类型和强制转换有关。先谢谢了!

【问题讨论】:

  • 请在问题中包含 full 错误消息。这对我们有很大帮助。
  • char 数据传递给strcat() 不是一个好主意。
  • p &lt; (p+4)(p+1) &lt; (p+4) 如果已定义,则始终为真。
  • 这无害,但p 作为for 的初始化部分是没有意义的。
  • 这里有几个问题: 1:你的内部 for 循环是无限的 2- strcat 期望类似 strcat(j,p) 而不是 strcat(*j,*p)。 3-即使您将代码放在我的第二点中,这在语义上也是不正确的 4-您正在做的这件事可以通过 POSIX 库中的正则表达式来完成,您可以在这里找到一个工作示例:stackoverflow.com/questions/1085083/…跨度>

标签: c parsing pointers


【解决方案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 必须足够大以包含提取的网址,否则您可能会遇到段错误。

【讨论】:

    【解决方案2】:

    这是解决您问题的简单方法:

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

    【讨论】:

    • 但是,如果“www”或“.edu”或两者都不在字符串`s1中怎么办?
    • 是的,我们可以添加一些条件来处理这个问题,但我相信提问者认为地址应该包含“www”和“.edu”
    • 是的,没错。我忽略了它。提问者甚至在“www”之后假设.。我建议对您的代码添加一些解释。
    【解决方案3】:

    不幸的是,有很多错误。您的编译失败,因为您在 strcat 需要 char* 时将 char 传递给它。即使它确实编译了,但它会崩溃。

    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';
    

    编辑:这似乎是一个家庭作业问题,所以我认为提及您当前的代码哪里出错会更有建设性,这样您就可以重新检查您在这些领域的知识。

    您的确切问题的答案是它无法编译,因为您取消引用字符串并因此将 2x char 而不是 char* 传递给 strcat()。

    【讨论】:

    • if 语句没有未定义的行为,因为短路评估适用于运算符 &amp;&amp;。由于此运算符是从左到右计算的,因此计算只会在 NUL 字符处停止。根据问题,也可以安全地假设两个子字符串都包含在字符串中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-29
    • 2014-03-25
    相关资源
    最近更新 更多