String splitter

Please support our C advertiser: Programming Forums - DaniWeb Sister Site
Reply

Join Date: Oct 2004
Posts: 274
Reputation: mmiikkee12 is an unknown quantity at this point 
Solved Threads: 5
mmiikkee12's Avatar
mmiikkee12 mmiikkee12 is offline Offline
Posting Whiz in Training

String splitter

 
0
  #1
Aug 26th, 2006
I tried writing a string splitter for my little operating system based on http://www.daniweb.com/code/snippet318.html but it didn't quite work. Here's my code:

  1. // BTW, this will eventually return a string containing the token_numth token. But I'm just trying to get it to work for now.
  2. void strsplit(const char *str, char splitchar, int token_num)
  3. {
  4. char *delimeter = "\0";
  5. delimeter[0] = splitchar;
  6. int i;
  7. strcpy(str, line);
  8. char *token = line; /* point to the beginning of the line */
  9. for (i = 0; *token; i++) /* loop through each character on the line */
  10. {
  11. /* search for delimiters */
  12. size_t len = strcspn(token, delimeter);
  13. token[len] = '\0';
  14. /* print the found text: use *.* in format to specify a maximum print size */
  15. printf("token[%2d] = \"%s\"\n", i, token);
  16. /* advance pointer by one more than the length of the found text */
  17. token += len + 1;
  18. }
  19. }

Then I call it like this:
  1. printf("strsplit test: /meow/moo/baa/something\n");
  2. strsplit("/meow/moo/baa/something", '/', 0);

But instead of the "meow", "moo", "baa", "something" I was expecting, I got this instead.
Popcorn 0.3 booting...
Build 60.
Looking for preloaded modules... none found
strsplit test: /meow/moo/baa/something
token[ 0] = ""
token[ 1] = "meow"
token[ 2] = "moo"
token[ 3] = "baa"
token[ 4] = "som"
token[ 5] = "thi"
token[ 6] = "g"
Any ideas on this?
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 15,442
Reputation: Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute 
Solved Threads: 1474
Team Colleague
Featured Poster
Ancient Dragon's Avatar
Ancient Dragon Ancient Dragon is offline Offline
Still Learning

Re: String splitter

 
0
  #2
Aug 26th, 2006
// BTW, this will eventually return a string containing the token_numth token. But I'm just trying to get it to work for now.
void strsplit(const char *str, char splitchar, int token_num)
{
	char *delimeter = "\0";
	delimeter[0] = splitchar;
^^^ delimiter is a ponter that oritinally points to someplace
in read-only memory.  You can't, in most cases, write to read-only memory like that.  
When you do, either you will get runtime errors or undefined behavior
	int i;
	strcpy(str, line);
^^^ 	attempt to copy something to read-only memory.  Note that your program passed a
 string literal to this function, and all (or most) string literals reside in read-only memory

        char *token = line; /* point to the beginning of the line */
^^^ where is variable line defined?  I don't see it anywhere

	for (i = 0; *token; i++) /* loop through each character on the line */
	{
		/* search for delimiters */
		size_t len = strcspn(token, delimeter);
		token[len] = '\0';
^^^ this is identical to strtok().  You may as well have used it.

		/* print the found text: use *.* in format to specify a maximum print size */
		printf("token[%2d] = \"%s\"\n", i, token);
		 /* advance pointer by one more than the length of the found text */
		token += len + 1;
	}
}
Last edited by Ancient Dragon; Aug 26th, 2006 at 12:35 pm.
Reply With Quote Quick reply to this message  
Join Date: Oct 2004
Posts: 274
Reputation: mmiikkee12 is an unknown quantity at this point 
Solved Threads: 5
mmiikkee12's Avatar
mmiikkee12 mmiikkee12 is offline Offline
Posting Whiz in Training

Re: String splitter

 
0
  #3
Aug 26th, 2006
^^^ delimiter is a ponter that oritinally points to someplace
in read-only memory. You can't, in most cases, write to read-only memory like that.
When you do, either you will get runtime errors or undefined behavior
^^^ attempt to copy something to read-only memory. Note that your program passed a
string literal to this function, and all (or most) string literals reside in read-only memory
Actually, all memory is marked writable, mainly because I was too lazy to look up the bits to set for read-only memory :-) Keep in mind:
for my little operating system
^^^ where is variable line defined? I don't see it anywhere
Sorry, forgot to include that part.
  1. char line[1024];
(EDIT: btw, this is right above the strsplit function.)

^^^ this is identical to strtok(). You may as well have used it.
No, because I never wrote a strtok after reading about it and how it sucked...

I've found that it works perfectly if there's a trailing / (or whatever delimeter) on the end of the string. But not every filename I'm parsing is a directory. Any idea on how else I can do this?
Last edited by mmiikkee12; Aug 26th, 2006 at 12:57 pm.
Reply With Quote Quick reply to this message  
Join Date: Oct 2004
Posts: 274
Reputation: mmiikkee12 is an unknown quantity at this point 
Solved Threads: 5
mmiikkee12's Avatar
mmiikkee12 mmiikkee12 is offline Offline
Posting Whiz in Training

Re: String splitter

 
1
  #4
Aug 26th, 2006
Got it!
For anyone googling for this, here's the code I used:
  1. char tmpbuf[1024];
  2. char retval[256];
  3.  
  4. char *strsplit(const char *str, char splitchar, int token_num)
  5. {
  6. strcpy(str, tmpbuf);
  7.  
  8. // fix a stupid bug
  9. if (tmpbuf[strlen(tmpbuf) - 1] != splitchar)
  10. {
  11. tmpbuf[strlen(tmpbuf)] = splitchar;
  12. tmpbuf[strlen(tmpbuf + 1)] = '\0';
  13. }
  14.  
  15. printf("%s\n", tmpbuf);
  16.  
  17. char *delimeter = "\0";
  18. delimeter[0] = splitchar;
  19. char *token = tmpbuf; /* point to the beginning of the line */
  20.  
  21. int i;
  22. for (i = 0; *token; i++) /* loop through each character on the line */
  23. {
  24. /* search for delimiters */
  25. size_t len = strcspn(token, delimeter);
  26. token[len] = '\0';
  27. /* print the found text: use *.* in format to specify a maximum print size */
  28. printf("token[%2d] = \"%s\"\n", i, token);
  29. if (i == token_num)
  30. {
  31. strncpy(token, retval, (len < 256? len:256));
  32. retval[(len < 256? len:256)] = '\0';
  33. return retval;
  34. }
  35. /* advance pointer by one more than the length of the found text */
  36. token += len + 1;
  37. }
  38. }
Last edited by mmiikkee12; Aug 26th, 2006 at 2:34 pm. Reason: yet another bugfix
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 15,442
Reputation: Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute 
Solved Threads: 1474
Team Colleague
Featured Poster
Ancient Dragon's Avatar
Ancient Dragon Ancient Dragon is offline Offline
Still Learning

Re: String splitter

 
0
  #5
Aug 26th, 2006
Originally Posted by mmiikkee12 View Post
Actually, all memory is marked writable, mainly because I was too lazy to look up the bits to set for read-only memory :-) Keep in mind:
Originally Posted by mmiikkee12 View Post
No, because I never wrote a strtok after reading about it and how it sucked...
I didn't realize you are writing your own os, your own compiler and all the functions that are normally in the standard C libraries. So your ocmpiler does not meet ansii standard c. Since you are the only one using it I suppose you can do whatever you like.
Last edited by Ancient Dragon; Aug 26th, 2006 at 2:57 pm.
Reply With Quote Quick reply to this message  
Join Date: Oct 2004
Posts: 274
Reputation: mmiikkee12 is an unknown quantity at this point 
Solved Threads: 5
mmiikkee12's Avatar
mmiikkee12 mmiikkee12 is offline Offline
Posting Whiz in Training

Re: String splitter

 
0
  #6
Aug 26th, 2006
No, I'm using GCC for now. But the point is it doesn't matter what's *supposed* to be readonly, because nothing enforces that once it's running
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 15,442
Reputation: Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute 
Solved Threads: 1474
Team Colleague
Featured Poster
Ancient Dragon's Avatar
Ancient Dragon Ancient Dragon is offline Offline
Still Learning

Re: String splitter

 
0
  #7
Aug 26th, 2006
you mean nothing enforces it on YOUR operating system. Run that program on *nix or MS-Windows and it will be different.
Reply With Quote Quick reply to this message  
Join Date: Oct 2004
Posts: 274
Reputation: mmiikkee12 is an unknown quantity at this point 
Solved Threads: 5
mmiikkee12's Avatar
mmiikkee12 mmiikkee12 is offline Offline
Posting Whiz in Training

Re: String splitter

 
0
  #8
Aug 26th, 2006
...it's not a program, this is the kernel.
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:



Similar Threads
Other Threads in the C Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC