-1

i've been tasked with writing a C program that recieves in input two strings (I can decide their content during the decleration) and returns a third string that is the concatenation of the two previous strings.

Moreover, I also need to replace each vowel of the third string with a star symbol '*'.

The main difficulty that i'm encountring is how to return a string from a function that takes in input two strings. A correction of my faulty code would also be much appreciated :)

Here is the code:

#include <stdio.h>
#include <string.h>

const char* concatvow (char *str1, char *str2);

int main()
{
    char word1[20]="One plus one ";
    char word2[20]="eqauls two";
    char *word3[20];
    
    concatvow(word1, word2);
    
    printf("%s", *word3);
    return 0;
}

const char* concatvow (char *str1, char *str2){

    char strfinal[20];
    int i=0;
    
    strcat(str1, str2);
    
    strcpy(strfinal, str1);
    
    if(strfinal[i]==65 || strfinal[i]==69 || strfinal[i]==73 || strfinal[i]==79 || strfinal[i]==85)            {
       strfinal[i]='*';
    }

return strfinal;
}

This is the output of my code.

main.c: In function ‘concatvow’:
main.c:33:8: warning: function returns address of local variable [-Wreturn-local-addr]
   33 | return strfinal;
      |        ^~~~~~~~


...Program finished with exit code 0
Press ENTER to exit console.

  • As the warning suggests, you can't return the address of a local variable, because that memory will no longer belong to the local variable as soon as you return from the method. You need to *either* pass in the target location to fill *or* use `malloc` (or equivalent) to allocate on-heap memory for the result. – Joachim Sauer Dec 31 '22 at 12:18
  • Does this answer your question? [error: function returns address of local variable](https://stackoverflow.com/questions/12380758/error-function-returns-address-of-local-variable) – Joachim Sauer Dec 31 '22 at 12:19
  • Yeah, I understand my error now, I now need to store the return value inside a variable that can be printed out. – Firas Tabai Dec 31 '22 at 12:47
  • And this: 'strcat(str1, str2);' blows str1. – Martin James Dec 31 '22 at 12:56
  • This is very similar to https://stackoverflow.com/questions/74927732/i-tried-creating-a-function-to-concatinate-str2-to-str1-using-pointers-but-it-do/74928275#74928275. – Simon Goater Dec 31 '22 at 14:31

2 Answers2

1

Any variable in C only holds in a memeory within a certain scope. As stated by a previous answer, the memory you are returning does not belong to that variable anymore. You could use heap memory with malloc.

 char *strfinal = malloc (sizeof (char) * 20);  
Viraj Shah
  • 11
  • 2
  • I understand now, it no longer gives me that error. Could you kindly give me some insight on how I can store the return value of that function inside a variable (word3) so I can print out later? I know how to do it with integers but not with strings. I tried to do: word3[20] = concatvow(word1, word2); C dosen't allow this, I've read some posts about it but I failed to implement the solution into my problems. Thanks for your kind and fast answer. – Firas Tabai Dec 31 '22 at 12:55
0

Cause of warning:

Variable strfinal is local non-static variable of concatvow() function which will cease to exist once returned from concatvow() function. Any attempt to access it outside of its lifetime lead to undefined behaviour.

Few other problem in your code:

  1. Check this statement of concatvow() function -

       strcat(str1, str2);
    
  • This will result in undefined behaviour if str1 will not have enough space to hold the resultant string after concatenation.
  • Even if str1 will have enough space, it will result in modifying str1. Is that intended?
  • If string literals passed to concatvow() function in place of array, it will attempt to modify the string literal which is something not recommended.
  1. Check for lower case vowels is missing while replacing vowels with '*' character.

Handling all these scenarios:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

const char * concatvow (const char *str1, const char *str2);

int main (void) {
    char word1[20] = "One plus one ";
    char word2[20] = "eqauls two";

    const char * word3 = concatvow (word1, word2);

    if (word3) {
        printf ("Result : %s\n", word3);
        free ((char *)word3);
    }
    
    return 0;
}

const char * concatvow (const char *str1, const char *str2) {
    if (!str1 || !str2) {
        // add error handling
        return NULL;
    }

    char * strfinal = malloc (strlen (str1) + strlen (str2) + 1); // +1 for null terminating character

    if (!strfinal) {
        // add error handling
        exit (EXIT_FAILURE);
    }

    // combine str1 and str2 and create one string
    sprintf (strfinal, "%s%s", str1, str2);

    // replace each vowel with a star symbol '*'
    for (char * p = strfinal; *p; ++p) {
        if (*p == 'A' || *p == 'a' ||
            *p == 'E' || *p == 'e' ||
            *p == 'I' || *p == 'i' ||
            *p == 'O' || *p == 'o' ||
            *p == 'U' || *p == 'u') {
            *p = '*';
        }
    }

    return strfinal;
}

Output:

# ./a.out
Result : *n* pl*s *n* *q**ls tw*
H.S.
  • 11,654
  • 2
  • 15
  • 32