Thread: printing a string from a pointer

  1. #1
    Registered User
    Join Date
    Jul 2007
    Posts
    39

    printing a string from a pointer

    Ok I've been fighting with this one all morning, finally got it working (I keep coding things as some of you may have noticed the hard way until I step back and go "OH" and put the easy way.) But I wanted the pointer to point to the starting of the second string in the first. However I can only get it to print the character it points to after finding the second string in the first. Also I can only get it working if I leave out the "if null" check for if it did not find the second string in the first.

    I suppose the check for null is more important than the pointer working properly, so why is it crashing when I leave in the "if null"?

    the idea is that if the string_in function gets to the end of the original string without finding a match it passes the address of the null character in the original string and this is what PTR is supposed to be set to.

    Code:
    #include <stdio.h>
    #include <string.h>
    #define MAX 80
    int string_in(char * orig, char * check);
    int main(void)
    {
    	char ins[MAX+1], fit[MAX+1];
    	char * ptr;
    	int done = 0;
    	
    	printf("Input two strings [q to quit]\n");
    	while(!done)
    		{
    		gets(ins);
        if (strcmp("q\0", ins) == 0)
            done = 1;
        else if (strlen(ins) != 0) 
    			{
    			gets(fit);
    			ptr = ins[string_in(ins, fit)];
    			if (strcmp("\0", ptr) == 0)
    				printf("\n&#37;s not found in %s\n", ins, fit);
    			else
    				printf("\n%s found in %s ||\t %c %p\n - - - - - -\n", fit, ins, ptr, ptr); 
    			
    			printf("Input two strings [q to quit]\n");
    			}
    		}
    
    	return 0;
    }						
    	
    int string_in(char * orig, char * check)
    	{
    	int i = 0, x;
    	x = strlen(check);
    	
    	while(orig[i] != '\0')
    		{
    		orig += i;
    		if (strncmp(orig, check, x) == 0)
    			break;
    		i++;
    		}
    
    	return (i);
    	}

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I don't think your search function is working quite rigth, you are incrementing "i", and you are also adding i to orig. If we say that orig is 0x1000, we look at the string as follows:

    Code:
    i = 0, orig = 0x1000
    i = 1, orig = 0x1001
    i = 2, orig = 0x1003
    i = 3, orig = 0x1006
    i = 4, orig = 0x100a
    ...
    This means that if you are not "lucky", you won't find the string - and you may also skip over the zero at the end of the string.

    --
    Mats

  3. #3
    Registered User
    Join Date
    Jul 2007
    Posts
    39
    I'm not sure how else to move letter by letter through a string and see if the second given string is found. As I said without the "if null" check it seems to work find after a few runs, I'll try some more word combinations though to check that.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    		orig += i;
    is DEFINITELY WRONG (well, the statement itself is perfectly valid, but not in the context where it is above. That is absolutely certain.

    You may want to consider "strncmp(orig + i, ...") instead.

    I may not have made myself clear in the above explanation of how the string is "not checked correctly". Let's assume our string is "Some little string with text", and you're looking for "string". The "Some little string with text" is located at address 0x1000 in memory.
    We get this sequence:
    Code:
    i = 0, orig = 0x1000  Contains: "Some little string with text"
    i = 1, orig = 0x1001  Contains: "ome little string with text"
    i = 2, orig = 0x1003  Contains: "e little string with text"
    i = 3, orig = 0x1006  Contains: "ittle string with text"
    i = 4, orig = 0x100A  Contains: "e string with text"
    i = 5, orig = 0x100F  Contains: "ing with text"
    i = 6, orig = 0x1015  Contains: "th text"
    i = 7, orig = 0x101C  Contains: // we have gone past the end of the string - it may be "rubbish" and not zero - may well continue until it crashes. [Or finds the string by pure coincidence]
    ...
    So, as you see, we won't find the string, because it doesn't match at 4, and we've skipped past the beginning when we get to 5.

    --
    Mats

  5. #5
    Registered User
    Join Date
    Jul 2007
    Posts
    39
    I understood that it's not going through the memory correctly, and before it was crashing when I had orig + i inside the strncmp, though now that I've moved it back in it seems to be working fine. But why is it crashing if I leave the "if ptr = \0" part in but runs fine without it?

    Especially since if i leave it out and run it with a set of strings that won't match, it does return a null for the pointer and an address of 0x0. And I assume changing it to check address values would not work, and I should be able to make it work for if the pointer is pointing to the end of the original string.

  6. #6
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    Well, the easy way to do this would be to call strstr(...) function (i'm saying this because i see that you are already calling some function of the standard string library).

    Using strncmp(..) like you do (but without the semantic error described by matsp) is not a "bad" idea either. Another way to do this (without using call to function defined in string.h) could looks like this...


    Code:
    int string_in(char * orig, char * check)
    {
    	int i;
    	int j;
    	int found = 0;
    
    	if (check[0] == '\0')
    	{
    		/* A: check is a null string */
    		i = -1;		// we will set i value to -1 but the
    				// way you are using the return value 
    				// of the function makes this dangerous
    	}
    
    	else
    	{
    		for (i = 0; (orig[i] != '\0') && (found == 0); i++)
    		{
    			for (j = 0; (orig[i+j] == check[j]) && (orig[i+j] != '\0') && (check[j] != '\0'); j++);
    
    			if (check[j] == '\0')
    			{
    				/* A: check is a substring of orig */
    				found = 1;
    			}
    		}
    
    		if (found == 0)
    		{
    			i = -1;
    		}
    
    		else
    		{
    			// i has been incremented at the end of the loop, so we have to decrement it
    			i--;
    		}
    	}
    
    	return i;
    }
    What's interesting in this is that, in fact, the inner loop is doing something close to the strncmp function. So this is about the same thing as your function.

  7. #7
    Registered User
    Join Date
    Jul 2007
    Posts
    39
    ok I get what you're saying, and the -1 won't be dangerous if I use a few if statements after string_in is called, but still why is it crashing when I leave in the "if ptr is null" section?

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    What does your "if ptr is null" bit look like?

    --
    Mats

  9. #9
    Registered User
    Join Date
    Jul 2007
    Posts
    39
    Code:
    if (strcmp("\0", ptr) == 0)
    				printf("\n%s not found in %s\n", ins, fit);
    			else
    				printf("\n%s found in %s ||\t %c %p\n - - - - - -\n", fit, ins, ptr, ptr);
    Right here are the two problems I originally asked bout, if I leave in everything between if and else it crashes. (I was thinking maybe I need to just change it to

    if(ptr == '\0')

    since it seems to only see ptr as a character. And that's the other trouble I thought I was setting ptr as merely pointing to the correct place in the first string, but when I set printf to %s it doesn't work right, and I wanted ptr to print out the remainder of the string beginning with the spot where the second string was found.

  10. #10
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    the problem is not if - the line before
    Code:
    ptr = ins[string_in(ins, fit)];
    			if (strcmp("\0", ptr) == 0)
    if the search failed you have
    ptr=ins[-1] - which is outof bounds access
    and when you use this pointer in some compariison (strcmp or == ) or some other way - behavior is undefined... You lucky to get a crash, that directly indicates the error.

    And without connection to the crash, to check if the ptr points to the empty string you can use
    if(*ptr == '\0')
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  2. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  3. Direct3D problem
    By cboard_member in forum Game Programming
    Replies: 10
    Last Post: 04-09-2006, 03:36 AM
  4. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  5. can anyone see anything wrong with this code
    By occ0708 in forum C++ Programming
    Replies: 6
    Last Post: 12-07-2004, 12:47 PM