Search code examples
carrayscharreturn-typefunction-calls

Can I use char[] or char* as a function's return value?


I want to know (I tried to but program freezes) if there's a way to create a function that returns a char* or a char[], so I don't have to modify the String I'm sending to the function, to learn how to make my code more eloquent.

#include <stdio.h>
#define LOW_LETTERS 97
#define CAP_LETTERS 65
#define N_LETTERS 26
#define DIFF 32
#define NUMBERS 48
#define N_DIGITS 9


void transformText ( char text[] )
{
    for ( int i = 0 ; text[i] != '\0' ; i++ )
    {
        if ( ( text[i] >= LOW_LETTERS ) && ( text[i]  <= LOW_LETTERS + N_LETTERS ) )
            text[ i ] = text [ i ] - DIFF ; //same letter, but upper case
        else
            if ( ( text [ i ] >= CAP_LETTERS ) && ( text[i] <= CAP_LETTERS + N_LETTERS ) )
                text [ i ] = text [ i ] + DIFF ; //same letter, but lower case
            else
                if ( text [i] >= NUMBERS && text[i] <= NUMBERS + N_DIGITS )
                    text[i] = '*'; //turns every number to a '*'
    }

}

int main (void)
{
    char text[] = "foOo123Oo44O99oO00" ;
    transformText ( text ) ;
    printf ( "%s\n", text ) ; //prints FOoO***oO**o**Oo**

    return 0 ;
}

This is the way I solved it, I think I'm having a memory leak thought, ain't I? Notice that I'm not modifying the original String, which is what I was intending to do, also I don't really know where to put the free(newText) so it is recognized, but still usable for main()

#include <stdio.h>
#define LOW_LETTERS 97
#define CAP_LETTERS 65
#define N_LETTERS 26
#define DIFF 32
#define NUMBERS 48
#define N_DIGITS 9
#define BUFFER 128


char* transformText ( char text[] )
{
    char *newText = (char *) malloc (BUFFER) ;
    for ( int i = 0 ; text[i] != '\0' ; i++ )
    {
        if ( ( text[i] >= LOW_LETTERS ) && ( text[i]  <= LOW_LETTERS + N_LETTERS ) )
            newText[ i ] = text [ i ] - DIFF ; //same letter, but upper case
        else
            if ( ( text [ i ] >= CAP_LETTERS ) && ( text[i] <= CAP_LETTERS + N_LETTERS ) )
                newText [ i ] = text [ i ] + DIFF ; //same letter, but lower case
            else
                if ( text [i] >= NUMBERS && text[i] <= NUMBERS + N_DIGITS )
                    newText[i] = '*'; //turns every number to a '*'
                else
                    newText[i] = text[i] ;
    }

    return newText ;
}

int main (void)
{
    char text[] = "foOo123Oo44O99oO00" ;

    printf ( "%s\n", transformText ( text ) ) ; //prints FOoO***oO**o**Oo**
    return 0 ;
}

Solution

  • In general, yes, you are all good to have a function that returns a char *, but you need to be careful about a few things, like

    • You need to be sure not to return the address of a local variable to the called function. That will create the issue of using an invalid memory in the caller. The preferable way is to allocate memory using malloc() or family and return the pointer. You need to free() the memory also, once you're done using it.
    • If you're going to make use of the returned pointer, you need to make sure of the validity of the returned pointer.

    EDIT:

    So, once you got the returned pointer in the caller and done with it's usage, you need to release the memory allocated earlier by calling free() and passing the pointer. In your case, it should look like

    char * res = transformText ( text );
    printf ( "%s\n", res );   // use the returned pointer
    free(res);                                  // release memory
    return 0 ;                                   // done