Thread: extracting char from a string

  1. #1
    Registered User
    Join Date
    Jun 2009
    Location
    US of A
    Posts
    305

    extracting char from a string

    I am trying to extract a number of characters from a string specified by the position where it has to begin and the number of characters to be extracted. The function seems to return some garbage value and it prints some funny characters. I was debugging it but unable to figure out the reason for it.


    [insert]
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    char* getsub(char *a, int loc, int len);
    
    int main(void)
    {
    	
    	char str[20] = "Rohan is a good boy";
    	char str1[20] = "Roh";
    	char str2[20] = "Rohan is a good boy";
    	char str3[20] = "Sohan";
    	char *sub;
    	char s;
    	int result;	
    
    	sub = getsub(str, 2, 4);
    	printf("\n%s", sub);
    
    	return 0;
    }
    
    char* getsub(char *a, int loc, int len)
    {
    	int lenstr;
    	int pos= 0, i,j;
    	char str[20];
    
    	lenstr = strlen(a);
    	for(pos = 0;pos< loc;pos++)
    	{
    		a++;
    	}
    
    	for(i =0; i<len;i++)
    	{
    		str[i]= *a;
    		a++;
    	}
    	
    	str[++i] = '\0';
    	return str;
    
    }

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You are returning a local pointer -- once the function finishes, str ceases to exist, but you have a pointer to it in your main program. You also increment i one too many times before writing your \0 character.

  3. #3
    Registered User
    Join Date
    Jun 2009
    Location
    US of A
    Posts
    305
    Does that imply that char str[20] in function getsub() has to be declared outside main?

    Or is there a way to get around this using some other thing?

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you declare it outside main, it will "work" in the sense that you will get a valid value out. The fun part will then be that you can only call the function once -- every time you call the function you'll get the same pointer back, because each function call is using the same "scratch area" to give the answer. That is, you'll get something like:
    Code:
    char *a, *b;
    a = getsub(str, 2, 4);
    printf("\"%s\"\n", a);  /* prints "han " */
    b = getsub(str, 4, 2);
    printf("\"%s\"\n", a); /* now prints "n ", even though a was not "changed" */
    You're left with two choices:
    1. Pass in the array that you want to be filled with your substring
    2. Use dynamic memory allocation to continually give you new pieces of memory to hand out

  5. #5
    Registered User
    Join Date
    Jun 2009
    Location
    US of A
    Posts
    305
    The fun part will then be that you can only call the function once -- every time you call the function you'll get the same pointer back, because each function call is using the same "scratch area" to give the answer. That is, you'll get something like:
    Code:

    char *a, *b;
    a = getsub(str, 2, 4);
    printf("\"%s\"\n", a); /* prints "han " */
    b = getsub(str, 4, 2);
    printf("\"%s\"\n", a); /* now prints "n ", even though a was not "changed"
    But if we are making successive calls to the function as you showed in the above case its a valid output. I mean its correct thats what the output should be when you call it for b.
    It works fine even the second time.

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    That's what the output should be when I call it for b, yes. Unfortunately, I called it with a instead.

  7. #7
    Registered User
    Join Date
    Jun 2009
    Location
    US of A
    Posts
    305
    Okay but if i make the declaration of

    char str[20]

    outside main it gives me instead of "han " it gives NOPQ

    I dont see anything wrong that i am doing.

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by roaan View Post
    Okay but if i make the declaration of

    char str[20]

    outside main it gives me instead of "han " it gives NOPQ

    I dont see anything wrong that i am doing.
    Well, you're doing something wrong. You'll have to post the new code.

  9. #9
    Registered User
    Join Date
    Jun 2009
    Location
    US of A
    Posts
    305
    Here it is:

    [insert]
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int search (char *a, char b);
    int isequals(char *a, char *b);
    int issmaller(char *a, char *b);
    int isgreater(char *a, char *b);
    char atpos(char *a, int loc);
    char* getsub(char *a, int loc, int len);
    
    char str4[20];
    
    int main(void)
    {
    	
    	char str[20] = "Rohan is a good boy";
    	char str1[20] = "Roh";
    	char str2[20] = "Rohan is a good boy";
    	char str3[20] = "Sohan";
    	char *sub;
    	char s;
    	int result;	
    	char *a, *b;
    
    	//printf("\nEnter a character to search");
    	//scanf("%c", &s);
    
    	/*result = search(str, s);
    	if(result == 1)
    		printf("\n Char found");
    	else
    		printf("\n Char not found");
    	*/
    
    	/*result = isequals(str, str1);
    	if(result == 1)
    		printf("\n Char found");
    	else
    		printf("\n Char not found");
    	*/
    
    	/*
    	result = issmaller(str, str1);
    	if(result == 1)
    		printf("\n 1st string smaller");
    	else
    		printf("\n Not smaller");
    
    	
    	result = isgreater(str3, str1);
    	if(result == 1)
    		printf("\n 1st string greater");
    	else
    		printf("\n 1st string not greater");
    	*/
    	
    	/*
    	s = atpos(str, 0);
    	if((s >= 65 && s < 91) || (s >= 97 && s < 122)) 
    	printf("\nChar is %c",s);
    	else
    		printf("\nYou are trying more than the lenght");
    	*/
    
    	sub = getsub(str, 2, 4);
    	printf("\n%s", sub);
    	
    	return 0;
    }
    
    char* getsub(char *a, int loc, int len)
    {
    	int lenstr;
    	int pos= 0, i,j;
    
    	for(i = 0;i< 20;i++)
    		str4[i] = NULL;
    
    	lenstr = strlen(a);
    	for(pos = 0;pos< loc;pos++)
    	{
    		a++;
    	}
    
    	for(i =0; i<len;i++)
    	{
    		str4[i]= a;
    		a++;
    	}
    	
    	str4[++i] = '\0';
    	return str4;
    }

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    What you have here doesn't compile.
    Leaving aside the unused variable warnings, you still have this:
    Code:
    temp.c: In function `char* getsub(char*, int, int)':
    temp.c:78: warning: converting to non-pointer type `char' from NULL
    temp.c:88: error: invalid conversion from `char*' to `char'

  11. #11
    Registered User
    Join Date
    Jun 2009
    Location
    US of A
    Posts
    305
    This compiles


    [insert]
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int search (char *a, char b);
    int isequals(char *a, char *b);
    int issmaller(char *a, char *b);
    int isgreater(char *a, char *b);
    char atpos(char *a, int loc);
    char* getsub(char *a, int loc, int len);
    
    char str4[20];
    
    int main(void)
    {
    	
    	char str[20] = "Rohan is a good boy";
    	char str1[20] = "Roh";
    	char str2[20] = "Rohan is a good boy";
    	char str3[20] = "Sohan";
    	char *sub;
    	char s;
    	int result;	
    	char *a, *b;
    
    	//printf("\nEnter a character to search");
    	//scanf("%c", &s);
    
    	/*result = search(str, s);
    	if(result == 1)
    		printf("\n Char found");
    	else
    		printf("\n Char not found");
    	*/
    
    	/*result = isequals(str, str1);
    	if(result == 1)
    		printf("\n Char found");
    	else
    		printf("\n Char not found");
    	*/
    
    	/*
    	result = issmaller(str, str1);
    	if(result == 1)
    		printf("\n 1st string smaller");
    	else
    		printf("\n Not smaller");
    
    	
    	result = isgreater(str3, str1);
    	if(result == 1)
    		printf("\n 1st string greater");
    	else
    		printf("\n 1st string not greater");
    	*/
    	
    	/*
    	s = atpos(str, 0);
    	if((s >= 65 && s < 91) || (s >= 97 && s < 122)) 
    	printf("\nChar is %c",s);
    	else
    		printf("\nYou are trying more than the lenght");
    	*/
    
    	sub = getsub(str, 2, 4);
    	printf("\n%s", sub);
    	
    	return 0;
    }
    
    char* getsub(char *a, int loc, int len)
    {
    	int lenstr;
    	int pos= 0, i,j;
    
    	for(i = 0;i< 20;i++)
    		str4[i] = NULL;
    
    	lenstr = strlen(a);
    	for(pos = 0;pos< loc;pos++)
    	{
    		a++;
    	}
    
    	for(i =0; i<len;i++)
    	{
    		str4[i]= a;
    		a++;
    	}
    	
    	str4[++i] = '\0';
    	return str4;
    }

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by roaan View Post
    This compiles


    [insert]
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int search (char *a, char b);
    int isequals(char *a, char *b);
    int issmaller(char *a, char *b);
    int isgreater(char *a, char *b);
    char atpos(char *a, int loc);
    char* getsub(char *a, int loc, int len);
    
    char str4[20];
    
    int main(void)
    {
    	
    	char str[20] = "Rohan is a good boy";
    	char str1[20] = "Roh";
    	char str2[20] = "Rohan is a good boy";
    	char str3[20] = "Sohan";
    	char *sub;
    	char s;
    	int result;	
    	char *a, *b;
    
    	//printf("\nEnter a character to search");
    	//scanf("%c", &s);
    
    	/*result = search(str, s);
    	if(result == 1)
    		printf("\n Char found");
    	else
    		printf("\n Char not found");
    	*/
    
    	/*result = isequals(str, str1);
    	if(result == 1)
    		printf("\n Char found");
    	else
    		printf("\n Char not found");
    	*/
    
    	/*
    	result = issmaller(str, str1);
    	if(result == 1)
    		printf("\n 1st string smaller");
    	else
    		printf("\n Not smaller");
    
    	
    	result = isgreater(str3, str1);
    	if(result == 1)
    		printf("\n 1st string greater");
    	else
    		printf("\n 1st string not greater");
    	*/
    	
    	/*
    	s = atpos(str, 0);
    	if((s >= 65 && s < 91) || (s >= 97 && s < 122)) 
    	printf("\nChar is %c",s);
    	else
    		printf("\nYou are trying more than the lenght");
    	*/
    
    	sub = getsub(str, 2, 4);
    	printf("\n%s", sub);
    	
    	return 0;
    }
    
    char* getsub(char *a, int loc, int len)
    {
    	int lenstr;
    	int pos= 0, i,j;
    
    	for(i = 0;i< 20;i++)
    		str4[i] = NULL;
    
    	lenstr = strlen(a);
    	for(pos = 0;pos< loc;pos++)
    	{
    		a++;
    	}
    
    	for(i =0; i<len;i++)
    	{
    		str4[i]= a;
    		a++;
    	}
    	
    	str4[++i] = '\0';
    	return str4;
    }
    No. No, it does not. The same thing as before -- str4[i] = a is so amazingly illegal. Either you are not understanding what your compiler is telling you, or your compiler is broken.

  13. #13
    Registered User
    Join Date
    Jun 2009
    Location
    US of A
    Posts
    305
    Oh i got it as you pointed out

    str4[i]= *a

    I suppose thats why it was giving NOPQ instead of "han " Now it works fine. But i dont know why the code was not compiling becasue everytime i ran the code it compiled and gave NOPQ.

    Thanks :-)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. char Handling, probably typical newbie stuff
    By Neolyth in forum C Programming
    Replies: 16
    Last Post: 06-21-2009, 04:05 AM
  2. Replies: 8
    Last Post: 04-25-2008, 02:45 PM
  3. String issues
    By The_professor in forum C++ Programming
    Replies: 7
    Last Post: 06-12-2007, 09:11 AM
  4. Linked List Help
    By CJ7Mudrover in forum C Programming
    Replies: 9
    Last Post: 03-10-2004, 10:33 PM
  5. "Operator must be a member function..." (Error)
    By Magos in forum C++ Programming
    Replies: 16
    Last Post: 10-28-2002, 02:54 PM