Thread: string strcpy

  1. #1
    Registered User
    Join Date
    Sep 2018
    Posts
    9

    string strcpy

    So one of the exercises im doing says "do a function that removes a file name"
    For example:
    Input: "http://www.example.com/index.h
    Output: "http://www.example.com"
    This is the function I made.
    Code:
    void remove_filename(char *url)
    {
        url += strlen(url) - 1; 
        
        while(*url != '/')
            --url;
        
        strcpy(url, "");
        //*url = '\0';
    }
    in both cases, using strcpy or putting a null char in the slash position, the function works for visual purposes: the output is "http://www.example.com". But it doesnt remove the "index.html" from the array. The function just overwrite a null char on the slash position, and this is telling to printf("%s") where should stop printing; and when I actually print the array with a loop, "index.html" its there. My question : Is there a way to remove it from the array? Or just overwrite it all with null chars?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > Is there a way to remove it from the array? Or just overwrite it all with null chars?
    For most practical purposes, just writing the \0 where you want the string to end suffices.
    printf("%s") will stop in the right place, strlen(), strcpy(), strcat() etc all do the right thing.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    What happens when the string doesn't contain any slashes?

    Also, the search for the last slash can be simplified by using strrchr() (which returns NULL when the character isn't found in the string).

  4. #4
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    You would probably be better off making two functions -

    1) returns the index of the last '/' character (or the last character of the string which should be '\0')

    2) replace character at the index returned by the other function

  5. #5
    Registered User
    Join Date
    Sep 2018
    Posts
    9
    Code:
    void remove_filename(char *url)
    {
        char *p;
        
        p = strrchr(url, '/');
        
        if(p != NULL && *(p-2) != ':')
            *p = '\0';
    }
    Thanks for the tip of strrchr(), I didnt know that function. Just checking with p != NULL and putting the null char solves the case where there isnt '/' in the string, but I noticed that in the case "http://www.example.com, it will cut from "http:/". So assuming that the input will be always an internet url (like the exercises says), I added the *(p-2) != ':'. So it works for the three cases : "http://www.example.com" , "http://www.example.com/index.html" and "www.example.com". Although I know "assuming" its not a good idea, I couldnt figure out another way of doing it

  6. #6
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    I couldnt figure out another way of doing it
    Did you consider writing your own function?

    I put together a quick solution. It doesn't do any boundary checks, but you can work them out if you want...
    Code:
    int lastOccurance(const char inputString[], char findChar)
    {
        int i = 0;
        int lastIndexFound = 0;
    
        for (i = 0; inputString[i] != '\0'; i++)
        {
            if (findChar == inputString[i])
                lastIndexFound = i;
        }
    
        return lastIndexFound;
    }
    
    int main(void)
    {
        char testString[] = "http://www.example.com/index.h";
    
        puts(testString);
    
        testString[lastOccurance(testString, '/')] = '\0';
    
        puts(testString);
    
        return EXIT_SUCCESS;
    }
    You can also have a seporate function before this designed to remove "http://" or "https://"

    Something like this...
    Code:
    char *RemoveWebProtocal(char *websiteStringPointer)
    {
        int slashCount = 0;
    
        while ((*websiteStringPointer != '\0') && (slashCount != 2))
        {
            if ('/' == *websiteStringPointer)
                slashCount++;
    
            websiteStringPointer++;
        }
    
        return websiteStringPointer;
    }

    These solutions can be improved upon, but hopefully I've got your imagination going
    Fact - Beethoven wrote his first symphony in C

  7. #7
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Quote Originally Posted by Click_here View Post
    Did you consider writing your own function?

    I put together a quick solution. It doesn't do any boundary checks, but you can work them out if you want...
    Code:
    int lastOccurance(const char inputString[], char findChar)
    {
        int i = 0;
        int lastIndexFound = 0;
    
        for (i = 0; inputString[i] != '\0'; i++)
        {
            if (findChar == inputString[i])
                lastIndexFound = i;
        }
    
        return lastIndexFound;
    }
    You could rewrite that to use strrchr(), which is likely to be highly optimized by the standard library authors:
    Code:
    int lastOccurance(const char inputString[], char findChar)
    {
        const char *p = strrchr(inputString, findChar);
        return p ? p - inputString : 0;
    }
    (Though I would make it return -1 if no occurrence of the character is found, or just use strrchr() directly and check for NULL.)

  8. #8
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    The user has already come up with a strrchr solution in a previous post, with a few mods to suit their problem. My little helper function was because they said that they couldn't think of another way of doing it.

    A feature of returning 0 (instead of -1 or NULL) if none is found is that the function removes the entire string if no '/' are found - i.e. The string was the file name. This may or may not suit the problem; I guess that it depends on how they want to implement it...

  9. #9
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    This is not "standard", but if you are using GCC and glibc, you can use regular expressions in C:

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <regex.h>
    
    int getUrlName( char **name, char *url )
    {
      static char regex[] = "^.+://([^/]+)/.*$";
      regex_t rex;
      regmatch_t rm[2]; // expected 2 matches:
                        // the main one and the group.
    
      // Compile extended posix regex (ignore case).
      if ( regcomp( &rex, regex, REG_EXTENDED | REG_ICASE ) )
        return 0;
    
      // Collect matches.
      if ( regexec( &rex, url, 2, rm, 0 ) )
      {
        regfree( &rex );
        return 0;
      }
    
      // Don't need rex anymore.
      regfree( &rex );
    
      // if the group has a match...
      if ( rm[1].rm_so >= 0 )
      {
        // allocate space for substring,
        // copy the match and returns with success.
        char *p;
        size_t chars = rm[1].rm_eo - rm[1].rm_so;
    
        p = malloc( sizeof(char) * chars + 1 );
        memcpy( p, url + rm[1].rm_so, chars );
        p[chars] = '\0';
    
        *name = p;
        
        return 1;
      }
    
      return 0;
    }
    
    int main( void )
    {
      char s[] = "http://example.com/index.html";
      char *p;
    
      if ( ! getUrlName( &p, s ) )
      {
        fputs( "Cannot find a match.\n", stderr );
        return EXIT_FAILURE;
      }
    
      printf( "Match: \"%s\".\n", p );
      free( p );
    
      return EXIT_SUCCESS;
    }
    Last edited by flp1969; 04-19-2019 at 08:38 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Comparing string (strcpy == char)
    By Phuoc Phan in forum C Programming
    Replies: 2
    Last Post: 11-26-2013, 04:00 PM
  2. String var corrupted after strcpy from another string
    By xeon321 in forum C Programming
    Replies: 8
    Last Post: 11-05-2012, 09:26 AM
  3. Replies: 5
    Last Post: 08-10-2011, 05:25 AM
  4. Copy String without using strcpy
    By sunrise in forum C Programming
    Replies: 11
    Last Post: 02-06-2005, 03:24 PM
  5. Create a new string before using strcpy?
    By Boksha in forum C++ Programming
    Replies: 3
    Last Post: 04-26-2002, 09:25 AM

Tags for this Thread