C and returning string

Started by
10 comments, last by DMINATOR 19 years, 4 months ago
Well I have been thinking about this for a long time, but still didn't find any easy solution. What i wan't to do is that some function would return me a char* string. For example :

#include <stdio.h>

// here it is
 ??? someFunc()
{
  return ???
}



int main()
{
  //i wan't to display a result from someFunc
  
  printf(" result = %s",someFunc());
  return 0;
}

This is how i wan't it to look. I can use static arrays to return it's value, but I wan't to find another way. Anyone can help ? Tnx in advance :)
Advertisement
A string is an array of chars. To access an array of chars you need a char pointer to a char array.

I haven't programmed C recently, but I believe it should look something like this

char [] someFunc(){
return (a char[]);
}

or using pointers:

char* someFunc(){
return (a char*);
}
if the content of the string in the function is in a static buffer (meaning one existing longer than the function call) then you can also do this:

const char *myFunc(){   return "bla bla bla";}


'const char *' means in this case a pointer to a constant string. a string literal "bla bla bla" is a constant string thus you can return it. if you have though some pointer like in this case you need to cast first.

char *buffer; // containing some string allocated earlierconst char *myFunc(){   return (const char *)buffer;}


donno if this helps. if you only need to retrieve strings for example of a name of an object you can use the later trick. just do not forget to free the buffer at the end [wink]

Life's like a Hydra... cut off one problem just to have two more popping out.
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine

Quote:Original post by FiveFootFreak
char [] someFunc(){
return (a char[]);
}


you can't return arrays like that.

Quote:Original post by FiveFootFreak
or using pointers:

char* someFunc(){
return (a char*);
}


if you return a local variable this will implode your computer!

string literals are implicitly static & constant so its okay to return there address (but its underfined behaviour if you try to modify them through a pointer), any local variable will be destroyed by scope once its scope has ended. What you need to do is dynamically allocate memory, this frees you from the shackles of scope but there is a price to pay for this, your responsible to free the memory when your finished with it yourself.

So you have 2 choices:

1:

#include <string.h>#include <stdio.h>#include <stdlib.h>char* foo(char* dst, const char* const bar) {    return strcpy(dst, bar);}int main() {   const char jim[] = "jimmy";   char f[sizeof(jim)];   printf("%s", foo(f, jim));}


2:

#include <string.h>#include <stdio.h>#include <stdlib.h>char* foo(const char* const bar) {    return strcpy((char*)malloc(strlen(bar) + 1), bar);}int main() {   char* f = foo("jimmy");   printf("%s", f);   free(f);}


former is probably better because you push allocation to clients so your function doesn't need to be concerned if it was dynamically allocated on the heap or is a local variable, you could change the code in the first to dynamically allocating the string on the heap, the function doesn't care its not in it's scope, it still works (of course do a check for null etc).

[Edited by - snk_kid on November 27, 2004 9:18:35 AM]
Well it's not really the thing i wanted to make, but it's really close. Well I finally got it, and it was as simple as it can get, so here is the code that uses string lists and displayes strings on the positions i specified (0,1,2).

There is also a function to find memory leaks at the end
it draws errors in debug window (or at console prompt) or none if everyting is ok.

#include <stdio.h>//memory leak debugger#define CRTDBG_MAP_ALLOCstruct WSTRUCT;//this is our wordsstruct WSTRUCT *words;void AddWord(char* word,int length);void FreeWords();struct WSTRUCT{      //word   char* word;   //pointer to next struct NULL if none   struct WSTRUCT *next;};//frees memory usedvoid FreeWords(){    //temp value used for freeing memory	struct WSTRUCT *temp;	while(words != NULL)   {      if(words->word != NULL)	  free(words->word);      	  temp = words;      	  //we select next item in the list	  words = words->next;	  //but we need to free current item	  free(temp);   }	//kill it	temp = NULL;}void AddWord(char* word,int length){	struct WSTRUCT *temp;	temp = words;	//this indicates that the are no 	//words in a list	//so we add word and exit	if(words == NULL)	{		//now we create new structure        words = (struct WSTRUCT*)malloc(sizeof(struct WSTRUCT));		//we create a new word        words->word = (char*)malloc(sizeof(char) * length); 		//and write a value to it	//	sprintf(words->word,"%s",word);	    _snprintf(words->word, length, "%.*s",length, word);		 		//and point the next pointer		//to NULL		words->next = NULL;		return;	}    else    while(temp->next != NULL)	{     temp = temp->next;	}	//now temp is the last structure we have	//so let's make it work     temp->next = (struct WSTRUCT*)malloc(sizeof(struct WSTRUCT));		//we create a new word     temp->next->word = (char*)malloc(sizeof(char) * length); 		//and write a value to it     sprintf(temp->next->word,"%.*s",length,word);		//and point the next pointer		//to NULL	 temp->next->next = NULL;	return;}//we output the word from the list// RETURNS:// NULL          - list is empty// NOT_FOUND     - there is no position in this list// ...           - we have found the wordchar* GetWord(int number){   int i = 0;    struct WSTRUCT *temp;      //checking is our words empty ?   if(words == NULL)   {	  temp = NULL;	  return "NULL";   }   temp = words;   //we walk untile we get the required word or until it's the end   for(i = 0; (i < number) && (temp->next != NULL);i++ )   {	   temp = temp->next;   }   //here it is   //we check have ve reached the desired number ?   if(i == number)   {	  //again we check if our word is empty or not      if(temp->word != NULL)	  //here is the place when we return STATIC? variable 	  return temp->word;      else 	  {		    temp = NULL;		   return "NULL";	  }   }   else //We have not found this position   {	   temp = NULL;	   return "NOT_FOUND";   }   temp = NULL;}int main(){   //let's make it clear that it is empty   words = NULL;   //now we just add a word and show the first 3 positions   printf("\n NO WORDS :\n\n");   printf("1=%s\n2=%s\n3=%s\n",GetWord(0),GetWord(1),GetWord(2));     printf("\n 1 WORD :\n\n");   //add new word   AddWord("word1",6);   printf("1=%s\n2=%s\n3=%s\n",GetWord(0),GetWord(1),GetWord(2));   printf("\n 2 WORDS :\n\n");   AddWord("word2",6);   printf("1=%s\n2=%s\n3=%s\n",GetWord(0),GetWord(1),GetWord(2));   printf("\n 3 WORDS :\n\n");   AddWord("word3",6);   printf("1=%s\n2=%s\n3=%s\n",GetWord(0),GetWord(1),GetWord(2));    printf("\n FREE () :\n\n");   //frees mem   FreeWords();   printf("1=%s\n2=%s\n3=%s\n",GetWord(0),GetWord(1),GetWord(2));     //searching for mempry leaks   _CrtDumpMemoryLeaks();  return 0;}



The way i return a value from the function is something like that :

char* MyFunc()
{
//it must be already allocated
return somestring;

}

//so in main i can call it

sprintf(" here is value = %s",MyFunc());

Well this simple and obvious way only works for strings that already are allocated (list for example), but if i wan't to create a string in the function itself :

char* MyFunc()
{
char* temp = (char*)malloc(somesize);

//some calculations
...

//and writing result
// Well how do i free it then ?
return ???

}
Look here for a function that returns a string.
Quote:Original post by Jimmy Valavanis
Look here for a function that returns a string.


Well it does return a string but it returns already allocated string, I was trying to find a way how to in one function allocate a string then pass it as return parameter and free it there in the same time.
Quote:Original post by DMINATOR
Quote:Original post by Jimmy Valavanis
Look here for a function that returns a string.


Well it does return a string but it returns already allocated string, I was trying to find a way how to in one function allocate a string then pass it as return parameter and free it there in the same time.


Well already i showed you an example (choice 2), like i already said if you dynamically allocate memory it will persist through out any scope but your reponsiiable to free it when your done.

You can't return the address of memory from a function & free memory at the same time, if lose the address you've lost away to free memory & thus casuing memory leaks.
YOu can return the address of an array.

char myarray[100];char (*function())[100]{return &myarray;}int main(){function();}
Ok tnx so there is no way unless i am using a static or array of chars. Well it was possible in C++ (borland specific)to use something like that :

AnsiString myfunc()
{
AnsiString temp = "anything i want";
return temp;
}

int main()
{
printf("result=%s",myfunc());

return 0;
}

This topic is closed to new replies.

Advertisement