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:

// 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;
	int i;
	strcpy(str, line);
	char *token = line; /* point to the beginning of the line */
	for (i = 0; *token; i++) /* loop through each character on the line */
	{
		/* search for delimiters */
		size_t len = strcspn(token, delimeter);
		token[len] = '\0';
		/* 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;
	}
}

Then I call it like this:

printf("strsplit test: /meow/moo/baa/something\n");
	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?

Recommended Answers

All 7 Replies

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

^^^ 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.

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?

Got it!
For anyone googling for this, here's the code I used:

char tmpbuf[1024];
char retval[256];

char *strsplit(const char *str, char splitchar, int token_num)
{
	strcpy(str, tmpbuf);
	
	// fix a stupid bug
	if (tmpbuf[strlen(tmpbuf) - 1] != splitchar)
	{
		tmpbuf[strlen(tmpbuf)] = splitchar;
		tmpbuf[strlen(tmpbuf + 1)] = '\0';
	}
		
	printf("%s\n", tmpbuf);
	
	char *delimeter = "\0";
	delimeter[0] = splitchar;
	char *token = tmpbuf; /* point to the beginning of the line */
	
	int i;
	for (i = 0; *token; i++) /* loop through each character on the line */
	{
		/* search for delimiters */
		size_t len = strcspn(token, delimeter);
		token[len] = '\0';
		/* print the found text: use *.* in format to specify a maximum print size */
		printf("token[%2d] = \"%s\"\n", i, token);
		if (i == token_num)
		{
			strncpy(token, retval, (len < 256? len:256));
			retval[(len < 256? len:256)] = '\0';
			return retval;
		}
		 /* advance pointer by one more than the length of the found text */
		token += len + 1;
	}
}

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:

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.

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 :)

you mean nothing enforces it on YOUR operating system. Run that program on *nix or MS-Windows and it will be different.

...it's not a program, this is the kernel.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.