C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 02-22-2009, 02:43 PM   #1
Registered User
 
w2look's Avatar
 
Join Date: Nov 2008
Posts: 31
Help with parsing a sentence.

I am writing a function to parse a sentence and print each separate word on a new line.
For some reason, I keep getting a Seg fault. Can anyone please tell me what I am doing wrong?
It is separating the words and printing them each on a new line, but then it Seg faults after the last word is printed.
Any advice would be much appreciated.

Code:
//prototype
void PrintList(char *ptrA[], const int size);

//call in main looks like this
ParseSentence(Buffer3);


//function
void ParseSentence(char *ptrA)
{
	char *words[80];
	const char delimiters[4] = {' ','.',',',';'};
	
	int size = strlen(ptrA);

	words[0] = strtok(ptrA, delimiters);
	printf("%s\n", words[0]);
	
	for(int i = 1; i > 0 && i < size - 1; i++)
	{
		words[i] = strtok(NULL, delimiters);
		printf("%s\n", words[i]);
	}

}
w2look is offline   Reply With Quote
Old 02-22-2009, 02:52 PM   #2
CSharpener
 
vart's Avatar
 
Join Date: Oct 2006
Posts: 5,242
second parameter of strtok is not array of char - it should be a nul-terminated string

also - you should check the return value of strtok before using it
__________________
If I have eight hours for cutting wood, I spend six sharpening my axe.
vart is offline   Reply With Quote
Old 02-22-2009, 02:59 PM   #3
Registered User
 
w2look's Avatar
 
Join Date: Nov 2008
Posts: 31
Quote:
Originally Posted by vart View Post
second parameter of strtok is not array of char - it should be a nul-terminated string

also - you should check the return value of strtok before using it
OK, I changed the code to the following.
Still getting the same result.

Code:
//prototype  *was wrong in initial post*
void ParseSentence(char *ptrA);

//call in main
ParseSentence(Buffer3);

//function
void ParseSentence(char *ptrA)
{
	char *words[80];
	
	int size = strlen(ptrA);

	words[0] = strtok(ptrA, " .,;");
	printf("%s\n", words[0]);
	
	for(int i = 1; i > 0 && i < size - 1; i++)
	{
		words[i] = strtok(NULL, " .,;");
		printf("%s\n", words[i]);
	}

}
w2look is offline   Reply With Quote
Old 02-22-2009, 03:02 PM   #4
and the Hat of Guessing
 
tabstop's Avatar
 
Join Date: Nov 2007
Posts: 8,740
If you have a 40-character string, the odds of you have 40 space-separated words in that string is zero. So your loop can't go by the number of characters, it needs to go until you run out of words.
tabstop is offline   Reply With Quote
Old 02-22-2009, 03:03 PM   #5
Registered User
 
w2look's Avatar
 
Join Date: Nov 2008
Posts: 31
Should I be copying the char array being passed to the function into a temp array before using strtok?

If so, how do I do that? I'm kinda new to C.
w2look is offline   Reply With Quote
Old 02-22-2009, 03:03 PM   #6
and the Hat of Guessing
 
tabstop's Avatar
 
Join Date: Nov 2007
Posts: 8,740
Quote:
Originally Posted by w2look View Post
Should I be copying the char array being passed to the function into a temp array before using strtok?

If so, how do I do that? I'm kinda new to C.
strtok will change the array passed in. If that's bad, then you need to make a copy. It's called strcpy.
tabstop is offline   Reply With Quote
Old 02-22-2009, 03:05 PM   #7
Registered User
 
w2look's Avatar
 
Join Date: Nov 2008
Posts: 31
Quote:
Originally Posted by tabstop View Post
If you have a 40-character string, the odds of you have 40 space-separated words in that string is zero. So your loop can't go by the number of characters, it needs to go until you run out of words.
Do I use an if statement for that?

like

if (character == NULL)
break;
w2look is offline   Reply With Quote
Old 02-22-2009, 03:13 PM   #8
Registered User
 
w2look's Avatar
 
Join Date: Nov 2008
Posts: 31
Tried changing it to this, but same result.

Code:
void ParseSentence(char *ptrA)
{
	char temp[80];
	char *words[80];
	strcpy(temp, ptrA);
	
	int size = strlen(temp);

	words[0] = strtok(temp, " .,;");
	
	printf("%s\n", words[0]);
	
	for(int i = 1; i < size - 1; i++)
	{
		words[i] = strtok(NULL, " .,;");
		printf("%s\n", words[i]);
	}

}
w2look is offline   Reply With Quote
Old 02-22-2009, 03:31 PM   #9
Registered User
 
w2look's Avatar
 
Join Date: Nov 2008
Posts: 31
I thought that there may be a possibility of another part of my program causing the problem
so I put everything regarding this function into it's own program to try and isolate the problem.
Here is the code I'm using:

Code:
#include <stdio.h>
#include <string.h>

//prototype
void ParseSentence(char *ptrA);

int main()						/* function main begins program execution */
{
	/* initialize and declare variables and containers */
	char Buffer3[80];
	
	/* prompt the user for input */
	printf("Please type a string of characters to be stored in Buffer3\n");
	/* scanf("%s", Buffer3);   Since this method does not work we can use gets instead */
	
	gets(Buffer3);
	
	printf("\n\n");
	ParseSentence(Buffer3);
	printf("\n\n");

    return 0;
}

//Break a sentence up into words and print them on separate lines
//Input: a NULL terminated string
//Output:a printed list of the words 
void ParseSentence(char *ptrA)
{
	char temp[80];

	strcpy(temp, ptrA);
	
	int size = strlen(temp);
	char *words[size];

	words[0] = strtok(temp, " .,;");
	
	printf("%s\n", words[0]);
	
	for(int i = 1; i < size - 1; i++)
	{
		words[i] = strtok(NULL, " .,;");
		printf("%s\n", words[i]);
		
		if(words[i] == NULL)
		{
			break;
		}
	}

}
Sample Input looks like:

This, my friends; is a string. of chars.

The output I get is:

This
my
friends
is
a
string
of
chars
Segmentation fault (core dumped)

Any suggestions as to how I can fix this?
w2look is offline   Reply With Quote
Old 02-22-2009, 03:34 PM   #10
and the Hat of Guessing
 
tabstop's Avatar
 
Join Date: Nov 2007
Posts: 8,740
Since your string has a length of 40, you are trying to print 40 words. Since you don't have 40 words, the computer complains. You must not use the length of the string to control how many words you print. You need to print until you run out of words. Look up strtok to see what happens when you run out of words.
tabstop is offline   Reply With Quote
Old 02-22-2009, 03:37 PM   #11
Registered User
 
w2look's Avatar
 
Join Date: Nov 2008
Posts: 31
Quote:
Originally Posted by tabstop View Post
Since your string has a length of 40, you are trying to print 40 words. Since you don't have 40 words, the computer complains. You must not use the length of the string to control how many words you print. You need to print until you run out of words. Look up strtok to see what happens when you run out of words.
I'm not quite sure where you got the # 40 from. The default size of the buffer for user input is 80 chars. But what you suggest makes sense. I guess I should be using a while loop instead of a for loop. I'll give it a try and see what happens.
w2look is offline   Reply With Quote
Old 02-22-2009, 03:39 PM   #12
and the Hat of Guessing
 
tabstop's Avatar
 
Join Date: Nov 2007
Posts: 8,740
Quote:
Originally Posted by w2look View Post
I'm not quite sure where you got the # 40 from. The default size of the buffer for user input is 80 chars. But what you suggest makes sense. I guess I should be using a while loop instead of a for loop. I'll give it a try and see what happens.
I got the 40 from scrolling too far and reading the previous code that used strlen. So yes, this code is trying to print 80 words, and you also don't have that many words.
tabstop is offline   Reply With Quote
Old 02-22-2009, 03:49 PM   #13
Registered User
 
w2look's Avatar
 
Join Date: Nov 2008
Posts: 31
I don't know what I was thinking, I didn't need a while loop at all.
If I was smarter and read your advice thoroughly, I would have saved myself some time.

i.e. "You need to print until you run out of words."

This simple change fixed it.

Code:
void ParseSentence(char *ptrA)
{
	char temp[80];

	strcpy(temp, ptrA);
	
	int size = strlen(temp);
	char *words[80];

	words[0] = strtok(temp, " .,;");
	
	printf("%s\n", words[0]);
	
	for(int i = 1; i < size - 1; i++)
	{
		if(words[i] == NULL)
		{
		break;
		}
		else
		{
		words[i] = strtok(NULL, " .,;");
		printf("%s\n", words[i]);
		}
	}

}
No more Seg fault.

Thanks for talking me through it tabstop.

Last edited by w2look; 02-22-2009 at 03:55 PM.
w2look is offline   Reply With Quote
Old 02-22-2009, 04:09 PM   #14
Registered User
 
w2look's Avatar
 
Join Date: Nov 2008
Posts: 31
looks like I spoke too soon.

no more seg fault, but not printing past the first word

hmm?
w2look is offline   Reply With Quote
Old 02-22-2009, 04:28 PM   #15
and the Hat of Guessing
 
tabstop's Avatar
 
Join Date: Nov 2007
Posts: 8,740
I'm guessing you have to fill the words array before doing the loop? Right now, you're checking whether words[1] exists, then if so, assign words[1]. Presumably it should go the other way around.
tabstop is offline   Reply With Quote
Reply

Tags
delimiters, function, parse, parsing, strings

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
vector<...>::iterators and insert - I'm stumped. Dino C++ Programming 6 12-25-2007 06:11 AM
draw tree graph of yacc parsing talz13 C Programming 2 07-23-2006 01:33 AM
mafia game italiano40 Game Programming 7 11-07-2005 01:22 AM
Parsing for Dummies MisterWonderful C++ Programming 4 03-08-2004 05:31 PM
I hate string parsing with a passion DavidP A Brief History of Cprogramming.com 2 03-19-2002 07:30 PM


All times are GMT -6. The time now is 12:11 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22