Thread: having some trouble calling a function in the main program

  1. #1
    Registered User
    Join Date
    Jun 2009
    Posts
    20

    having some trouble calling a function in the main program

    Hi everyone. I'm writing this program that takes a sentence and breaks it up into words and spits that out in a vertical column. I couldn't use the "strtok" function so I wrote one from scratch. Anyways, I believe I wrote it correctly and now I'm trying to call it into the program. I have to be honest, I don't have much knowledge on functions especially when pointers are involved. Can anyone explain what I should be doing?

    Code:
    #include <stdio.h>
    #include <string.h>
    #define MAXLENGTH 256
    
    char * next_word(char *instring, char **new_start);
    
    int main ()
    {
    	char buffer[MAXLENGTH];
    	
    
    	printf("Enter text of line");
    
    	while (1)
    	{
    		fgets(buffer, MAXLENGTH, stdin);
    		if (buffer[0] == '\n')
    			break;
    		
                    puts(buffer);
    		//need help with what to do here
    		next_word(buffer, MAXLENGTH);
    	        
    		return 0;
    	}
    }
    
    
    char *next_word(char *instring, char **new_start)
    {
    	char *token;
    
    	if(instring == NULL)
    		instring=*new_start;
    
    	instring += strspn(instring, '\0');
    	if (*instring == '\0');
    	return NULL;
    
    	token = instring;
    	instring = strpbrk(token, '\0');
    	if (instring = NULL)
    	{
    		*new_start = strchr(token, '\0');
    	}
    	else
    	{
    		*instring = '\0';
    		*new_start= instring +1;
    	}
    	return token;
    }

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> next_word(buffer, MAXLENGTH);

    Why are you passing an integer as the second parameter? Form a pointer to buffer, and pass the address of that pointer. Also, you'll probably want to call next_word in a loop.

    Finally, before you go any further, try printing the values of variables at various points of execution to see what's going on:

    Code:
    char *next_word(char *instring, char **new_start)
    {
    	char *token;
    
    	if(instring == NULL)
    		instring=*new_start;
    
    	printf("Address of instring: %x\n", instring);
    	printf("Address of newstart: %x\n", *new_start);
    
    	instring += strspn(instring, '\0');
    
    	printf("Address of instring after strspn: %x\n", instring);
    	
    	if (*instring == '\0');
    	return NULL;
    
    	token = instring;
    	instring = strpbrk(token, '\0');
    
    	printf("Address of instring after strpbrk: %x\n", instring);
    
    	if (instring = NULL)
    	{
    		*new_start = strchr(token, '\0');
    	}
    	else
    	{
    		*instring = '\0';
    		*new_start= instring +1;
    	}
    	return token;
    }
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #3
    Registered User
    Join Date
    Jun 2009
    Posts
    20
    Quote Originally Posted by Sebastiani View Post
    >> next_word(buffer, MAXLENGTH);

    Why are you passing an integer as the second parameter? Form a pointer to buffer, and pass the address of that pointer. Also, you'll probably want to call next_word in a loop.

    Finally, before you go any further, try printing the values of variables at various points of execution to see what's going on:

    Code:
    char *next_word(char *instring, char **new_start)
    {
    	char *token;
    
    	if(instring == NULL)
    		instring=*new_start;
    
    	printf("Address of instring: %x\n", instring);
    	printf("Address of newstart: %x\n", *new_start);
    
    	instring += strspn(instring, '\0');
    
    	printf("Address of instring after strspn: %x\n", instring);
    	
    	if (*instring == '\0');
    	return NULL;
    
    	token = instring;
    	instring = strpbrk(token, '\0');
    
    	printf("Address of instring after strpbrk: %x\n", instring);
    
    	if (instring = NULL)
    	{
    		*new_start = strchr(token, '\0');
    	}
    	else
    	{
    		*instring = '\0';
    		*new_start= instring +1;
    	}
    	return token;
    }
    yeah honestly I had no idea what I was doing with calling the function. Now I feel like my strtok code isnt going to work properly Is there a way I can test it without calling it into the main program?

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> Is there a way I can test it without calling it into the main program?

    Well, you have to call it from *somewhere* in the main program if you want to see it's output. You don't have to call it in a loop though, if that's what you mean. Just prefill the buffer with data and call the function once to test it. But anyway, it would probably be more useful to call it in a loop, so that you can see how it reacts as it traverses the text.

    Another thing that you should do is look up the documentation on every function you're using (strspan, strpbrk, etc) to make sure that you're calling them correctly.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  5. #5
    Registered User
    Join Date
    Jun 2009
    Posts
    20
    Okay I think I got it, but it gives me the assignment makes integer from pointer w/o cast error. Also, I believe Im getting a segmentation fault after I type in my sentence.

    Code:
    #include <stdio.h>
    #include <string.h>
    #define MAXLENGTH 256
    
    //function portotype
    char * next_word(char *instring, char **new_start);
    
    
    int main ()
    {
    	char instring[MAXLENGTH];
    	int words;
    	char *parsed=NULL;
    
    	printf("Enter text of line");
    
    	while (1)
    	{
    		fgets(instring, MAXLENGTH, stdin);
    		if (instring[0] == '\n')
    			break;
    		
    		//puts(instring);
    
    		//need help with what to do here
    		words=next_word(instring, &parsed);
    		
    		
    		return 0;
    	}
    }
    
    
    char *next_word(char *instring, char **new_start)
    {
    	char *token;
    
    	if(instring == NULL)
    		instring=*new_start;
    
    	//printf("Adress of instring: %x\n", instring);
    	//printf("Addres of newstart: %x\n", *new_start);
    	
    	instring += strspn(instring, '\0');
    	
    	//printf("Address of instring after strspn: %x\n", instring);
    
    	if (*instring == '\0');
    	return NULL;
    
    	token = instring;
    	instring = strpbrk(token, '\0');
    
    	//printf("Address of instring after strpbrk: %x\n", instring);
    
    	if (instring = NULL)
    	{
    		*new_start = strchr(token, '\0');
    	}
    	else
    	{
    		*instring = '\0';
    		*new_start= instring +1;
    	}
    	return token;
    }

  6. #6
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> char *parsed=NULL;

    It crashes because the code dereferenced a NULL pointer. Set it to the address of the buffer. And don't comment out the print statements (and in fact, add more, as necessary), they'll help pinpoint what the program is doing before it crashes.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  7. #7
    Registered User
    Join Date
    Jun 2009
    Posts
    20
    Quote Originally Posted by Sebastiani View Post
    >> char *parsed=NULL;

    It crashes because the code dereferenced a NULL pointer. Set it to the address of the buffer. And don't comment out the print statements (and in fact, add more, as necessary), they'll help pinpoint what the program is doing before it crashes.
    so char* parsed=instring;?
    Ill definitely be uncommenting the print statements once this program makes it to that point lol

  8. #8
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> so char* parsed=instring;?

    No, set it to buffer inside main.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  9. #9
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> I couldn't use the "strtok" function so I wrote one from scratch.

    Does the function have to work like strtok (as in "is that part of the assigment?"), because if not, I would recommend a different approach. strtok is a sloppy function IMO (and uses static variables internally, which creates various problems), and you could probably do much better than that with a more simple, straightforward function.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  10. #10
    Registered User
    Join Date
    Jun 2009
    Posts
    20
    Quote Originally Posted by Sebastiani View Post
    >> I couldn't use the "strtok" function so I wrote one from scratch.

    Does the function have to work like strtok (as in "is that part of the assigment?"), because if not, I would recommend a different approach. strtok is a sloppy function IMO (and uses static variables internally, which creates various problems), and you could probably do much better than that with a more simple, straightforward function.
    It does not have to work like strtok, thats the only thing i could find to get me started. The only requirement is it have this function:

    char *next_word(char *instring, char **new_start)

    Do you have any ideas for a simpler approach? Everything I researched referred to the strtok function, including the book im using.

  11. #11
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> The only requirement is it have this function:

    Well, then I'd imagine then that the function *does* have to work like strtok (it's being fed into some sort of uniform driver code, correct)? Assuming that is the case, the first thing you should do is set up the program to use strtok for testing purposes. Once you have all of that working properly you can move on to implementing your own version.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  12. #12
    Registered User
    Join Date
    Jun 2009
    Posts
    20
    Quote Originally Posted by Sebastiani View Post
    >> The only requirement is it have this function:

    Well, then I'd imagine then that the function *does* have to work like strtok (it's being fed into some sort of uniform driver code, correct)? Assuming that is the case, the first thing you should do is set up the program to use strtok for testing purposes. Once you have all of that working properly you can move on to implementing your own version.
    This might be a stupid question, but I was thinking, would it be possible to use strtok within that function? I know how to make this program using strtok, so it would be awesome if i could just toss that into the function

    Code:
    #include <stdio.h>
    #include <string.h>
    #define MAXLENGTH 256
    
    int main()
    {
             char instring[MAXLENGTH];
             char *word;
    
             printf("Enter text of line");
    
             while (1)
             {     
                   fgets(instring, MAXLENGTH, stdin);
                   if (instring[0] == '\n')
                          break;
             }
    
             words = strtok (instrings, " ");
    
             while (words != NULL)
             {
                     printf("%s\n", words);
                     words = strtok (NULL, " ");
             }
     
              return 0;
    
    }
    Last edited by CMakesMeSad :(; 06-25-2009 at 08:21 PM.

  13. #13
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    First off all, let me say that I was wrong about the signature being the same as strtok - it's not. Sorry about that.

    >> would it be possible to use strtok within that function?

    I don't see why not.

    >> I know how to make this program using strtok

    OK, there are a couple of things wrong here with the logic. It should be something like:

    Code:
    	Loop: 
    	[Prompt user for input]
    	[Break out of loop if input is empty]
    		Loop: 
    		[Call strok, Break out of loop if result is NULL]
    		[Print current word]
    Finally, be sure to look up the documentation for strtok to be sure that you are using it correctly.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  14. #14
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> Last edited by CMakesMeSad ; Today at 10:21 PM.

    You still need to put the strtok loop inside of the input loop.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  15. #15
    Registered User
    Join Date
    Jun 2009
    Posts
    20
    Im going to try to finish the current program since it seems like im having trouble even using the strtok function. I fixed the compiling errors that i was receiving, but im still segfaulting when I run the program.


    Code:
    #include <stdio.h>
    #include <string.h>
    #define MAXLENGTH 256
    
    //function portotype
    char * next_word(char *instring, char **new_start);
    
    
    int main ()
    {
    	char instring[MAXLENGTH];
    	char *words;
    	char *parsed=NULL;
    
    	printf("Enter text of line");
    
    	while (1)
    	{
    		fgets(instring, MAXLENGTH, stdin);
    		if (instring[0] == '\n')
    			break;
    		
    		//puts(instring);
    
    		//need help with what to do here
    		words=next_word(instring, &parsed );
    		
    		
    		return 0;
    	}
    }
    
    
    char *next_word(char *instring, char **new_start)
    {
    	char *token;
    
    	if(instring == NULL)
    		instring=*new_start;
    
    	printf("Adress of instring: %x\n", instring);
    	printf("Addres of newstart: %x\n", *new_start);
    	
    	instring += strspn(instring, '\0');
    	
    	printf("Address of instring after strspn: %x\n", instring);
    
    	if (*instring == '\0')
    	{
    	return NULL;
    	}
    
    	token = instring;
    	instring = strpbrk(token, '\0');
    
    	printf("Address of instring after strpbrk: %x\n", instring);
    
    	if (instring = NULL)
    	{
    		*new_start = strchr(token, '\0');
    	}
    	else
    	{
    		*instring = '\0';
    		*new_start= instring +1;
    	}
    	return token;
    }
    Am I still dereferencing a null pointer?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  2. Replies: 6
    Last Post: 01-26-2009, 08:01 PM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. Return Statement
    By Daveo in forum C Programming
    Replies: 21
    Last Post: 11-09-2004, 05:14 AM
  5. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM