7

I have trouble with my code and I need your help! What I need to do is to write a function that will extract the web address that starts from www. and ends with .edu from an inputted string. The inputted string will have no spaces in it so scanf() should work well here.

For example:
http://www.school.edu/admission. The extracted address should be www.school.edu.

This is what I came up with so far, it obviously didn't work, and I can't think of anything else unfortunately.

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

The function has to use pointer arithmetic. The errors I get have something to do with incompatible types and casting. Thanks ahead!

nalzok
  • 14,965
  • 21
  • 72
  • 139
Iceberg233
  • 81
  • 3
  • 2
    Please include the **full** error message in the question. That would help us a lot. – Sean Francis N. Ballais Feb 28 '16 at 07:08
  • Passing `char` data to `strcat()` isn't a good idea. – MikeCAT Feb 28 '16 at 07:13
  • 2
    `p < (p+4)` and `(p+1) < (p+4)` are always true if they are defined. – MikeCAT Feb 28 '16 at 07:14
  • This is not harmful, but `p` as initializer part of `for` is meaningless. – MikeCAT Feb 28 '16 at 07:15
  • There are couple of issues here: 1: your inner for loops are true infinitely 2- strcat expected something like strcat(j,p) instead of strcat(*j,*p). 3- even you put the code in my second point, this would semantically be incorrect 4- this thing that you are doing can be done by regular expressions which is in POSIX libraries and you can find a working example here: http://stackoverflow.com/questions/1085083/regular-expressions-in-c-examples – Pooya Feb 28 '16 at 07:27
  • Is it allowed to use the `strstr` function? – Martin Zabel Feb 28 '16 at 11:42

3 Answers3

1

So the most trivial approach might be:

#include <stdio.h>

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

Now, here goes the fixed code:

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

Note that s2 must be large enough to contain the extracted web address, or you may get a segfault.

nalzok
  • 14,965
  • 21
  • 72
  • 139
0

This is an easy solution for your problem:

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;
}
fedi
  • 368
  • 3
  • 7
  • 18
-1

There is a lot wrong unfortunately. Your compilation is failing because you pass a char to strcat when it expects a char*. Even if it did compile though it would crash.

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

EDIT: This seems like a homework question, so I thought it would be more constructive to mention where your current code is going wrong, so you can recheck your knowledge in those areas.

The answer to your exact question is it doesn't compile because you dereference the string and hence pass 2x char instead of char* to strcat().

Jarra McIntyre
  • 1,265
  • 8
  • 13
  • The `if` statements have no undefined behaviour because short circuit evaluation is applied for operator `&&`. As this operator is evaluated from left to right, the evaluation just stops at the NUL character. According to the question, one can also safely assume that both sub-strings are contained within the string. – Martin Zabel Feb 28 '16 at 15:44