Thread: extracting a specific part out of a string (errors in my code?)

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    3

    extracting a specific part out of a string (errors in my code?)

    Hello guys,

    I have the following task to do:

    given a string (char * buf) in a specific way ("putfile $[path of file]") I want to extract the filename out of the filepath with a function called extract_name.

    Here's the code:

    Code:
    char* extract_name(char* buf){
    	int length = strlen(buf)-1;
    	int count  = -1;
    	int i = 0;
    	char * fname;
    	char c;
    	for(i = length; i>=0; i--){	//go backwards through string to gain knowledge of filename length
    		c = buf[length];
    		if((c == '/') || (c == '\\') || (c == '$')){ //either of these chars show me I have reached the
    													 //beginning of my filename, so I leave the loop
    			break;
    		}
    		count++;
    		length--;
    	}
    	fname = (char*)calloc(count+1, sizeof(char));	//allocate free space
    	fname[count+1] = '\0';							//put string termination symbol
    	length = strlen(buf)-1;							//reset length
    	
    	for(i = count; i>=0; i--){						//go backwards through string
    		fname[i] = buf[length];						//and set the characters accordingly
    		i--;
    		length--;
    	}
    	return fname;									//return pointer to name
    }
    Now, my problem is, that I get no filename back. It's just empty.

    Maybe you need to see this part of code too?

    Code:
            char *name;
            name = extract_name(message);
    	path  = (char*)calloc(10 + strlen(act_user->username) + strlen(name), sizeof(char)); 
    									
    									
    	sprintf(path, "./uploads/%s/%s",act_user->username,name); //create  path-string
    Anyone can tell me where exactly my error is? Or should I do it in a different way alltogether?

  2. #2
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Yarr ugly!

    Code:
    #include <stdio.h>
    #include <stdlib.h> 
    
    #define MAX_PATH 256
    
    char * extract_name(char * buf)
    {
       char * path = NULL;
    
       path = malloc(MAX_PATH);
       if(!path)
          return NULL;
    
       sscanf(buf, "%*s %256s", path);
    
       return path; 
    }
    
    int main(void)
    {
       char * a;
    
       a = extract_name("putfile /foo/bar");
       if(a)
       {
          printf("%s\n", a);
          free(a);
       }
       
       return 0;
    }
    I haven't done the work for you either. It's an ugly solution, you can do it your way and write a far nicer one. Also don't cast calloc().

    1. You don't need to traverse backwards. You know the length of the filename is the length of the buffer - the start bit.
    2. You can use strncpy() you know .

    In reality I'd probably strip all the trailing and leading spaces from the buffer, then again from the path after I parsed it. Probably with the above method if I was feeling lazy
    Last edited by zacs7; 01-15-2009 at 06:34 AM.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    You should be aware of strrchr:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    char *extract_name (char *fpathname) {
    	char *ptr=strrchr(fpathname,'/');
    	ptr++;
    	return ptr;
    }
    
    
    int main() {
    	char example[]="/home/user/somedir/afile.o",
    		*shortname=extract_name(example);
    	printf("%s\n",shortname);
    }
    BE AWARE THAT THIS RETURNS ONLY A POINTER INTO THE ORIGINAL STRING. However, it does work and demonstrate strrchr, which you need to look up.
    Last edited by MK27; 01-15-2009 at 06:44 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Yes, but "./foo/bar" isn't the same as "/foo/bar" nor is "../foo/bar":-)

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    I really don't think you should do this:

    Quote Originally Posted by snpnx View Post
    if((c == '/') || (c == '\\') || (c == '$')){ //either of these chars show me I have
    If portability is a factor use an ifdef statement:
    Code:
    #ifdef WIN32
    #define SC 92     /* a "\"   */
    #else 
    #define SC 47     /* a  "/" */
    #endif
    [...]
    char *ptr=strrchr(fpathname,SC);
    ps. an honest question -- what OS allows "$" in filenames or paths?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by zacs7 View Post
    Yes, but "./foo/bar" isn't the same as "/foo/bar" nor is "../foo/bar":-)
    Well, that's true. Also, blue is not the same as green. Is this relevent?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    Jan 2009
    Posts
    3
    @zacs7: why no use of calloc?

    @MK27: an honest question -- what OS allows "$" in filenames or paths?

    Not a question of the OS, it was just needed since I did go backwards through the String and thought if the user puts in the filename without any leading './' I know it's right after the '$'. But I'll use strrchr, which I didn't know and let the user know that he needs to give me a '/' with the filename.


    @all
    Thanks for your help, it should be enough for me to figure it out. If I have questions again, I'll come back

  8. #8
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    > ps. an honest question -- what OS allows "$" in filenames or paths?
    The ext2/3 filesystems. So Linux :-)

  9. #9
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    I said don't cast calloc(). See the FAQ.

  10. #10
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by snpnx View Post
    Not a question of the OS, it was just needed since I did go backwards through the String and thought if the user puts in the filename without any leading './' I know it's right after the '$'. But I'll use strrchr, which I didn't know and let the user know that he needs to give me a '/' with the filename.
    So you mean the end of the command prompt. That WILL NOT be in your string. Also, if the string does not contain any slashes, it is not a path and sticking one on the front won't change that. This is like saying I can make an apple out of an orange by putting a hat on it.

    Pick, pick pick...anyway good luck
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    	for(i = count; i>=0; i--){						//go backwards through string
    		fname[i] = buf[length];						//and set the characters accordingly
    		i--;
    		length--;
    	}
    Code in red does what??

    Code:
    	fname = (char*)calloc(count+1, sizeof(char));	//allocate free space
    	fname[count+1] = '\0';							//put string termination symbol
    Probably should not access outside of the member you have allocated - it tends to cause bad things to happen. Remember, an n-element array has valid a valid index range of 0 .. (n-1).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Registered User
    Join Date
    Jan 2009
    Posts
    3
    Quote Originally Posted by matsp View Post
    Code:
    	for(i = count; i>=0; i--){						//go backwards through string
    		fname[i] = buf[length];						//and set the characters accordingly
    		i--;
    		length--;
    	}
    The code in red was an error, I did it with a while loop before and forgot to take out the decrement.

    Code:
    	fname = (char*)calloc(count+1, sizeof(char));	//allocate free space
    	fname[count+1] = '\0';							//put string termination symbol
    Probably should not access outside of the member you have allocated - it tends to cause bad things to happen. Remember, an n-element array has valid a valid index range of 0 .. (n-1).

    --
    Mats
    Right, you should not access outside of the allocation, I dunno why I didn't see that O_o

  13. #13
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by zacs7 View Post
    > ps. an honest question -- what OS allows "$" in filenames or paths?
    The ext2/3 filesystems. So Linux :-)
    Okay, $ is allowed in a filename as long as it's not the first character (eg. the$.file) but in this:
    Code:
    prompt$ /home/user/file.txt
    $ is not part of the filename or path.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Error in Recursive String Palindrome Code
    By clegs in forum C Programming
    Replies: 13
    Last Post: 12-21-2008, 12:36 PM
  2. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  3. Can someone help me understand this example program
    By Guti14 in forum C Programming
    Replies: 6
    Last Post: 09-06-2004, 12:19 PM
  4. Linked List Help
    By CJ7Mudrover in forum C Programming
    Replies: 9
    Last Post: 03-10-2004, 10:33 PM
  5. True ASM vs. Fake ASM ????
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 04-02-2003, 04:28 AM

Tags for this Thread