Error calling function that returns string in C

Asked

Viewed 337 times

3

I made a program that asks for name and surname to be concatenated through a function:

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

int main(void){
    //Declarando Funçãoo
    char retornaNome(char nome[], char sobrenome[]);
    //Ariaveis
    char nome[20], sobrenome[20], nomeFinal[100];

    //Entrando com o nome
    printf("Digite seu nome: ");
    setbuf(stdin, 0);
    fgets(nome, 20, stdin);
    nome[strlen(nome)-1] = '\0';

    //Entrando com sobrenome
    printf("Digite seu sobrenome: ");
    setbuf(stdin, 0);
    fgets(sobrenome, 20, stdin);
    sobrenome[strlen(sobrenome)-1] = '\n';

    //Chamando a função
    nomeFinal = retornaNome(nome, sobrenome);

    printf("%s\n", nomeFinal);

    return 0;
}

char retornaNome(char nome[], char sobrenome[]){

    char nomeFinal[60];

    //Calculando tamanho das palavras
    int x = strlen(nome);
    int y = strlen(sobrenome);

    //Adribuindo nome e sobrenome a nomeFinal
    for(int i = 0; i < x; i++){
        nomeFinal[i] = nome[i];
    }
    for(int i = 0; i < y; i++){
        nomeFinal[x+i] = nome[i];
    }

    //Retornando nomeFinal
    return nomeFinal;
}

But this giving 3 exits

Retorna.c: In function ‘main’:
Retorna.c:19:15: error: assignment to expression with array type
 nomeFinal = retornaNome(nome, sobrenome);
           ^
Retorna.c: In function ‘retornaNome’:
Retorna.c:42:12: warning: return makes integer from pointer without a cast      [-Wint-conversion]
 return nomeFinal;
        ^
Retorna.c:42:12: warning: function returns address of local variable [-Wreturn-local-addr]

2 are just one warnings, but error at first I found no answer on how to resolve this error.

3 answers

6


In C you cannot return one string, even because they strictly don’t exist. You can return a pointer to a string. You might be thinking so just return a type char *. This is what everyone thinks naively. And there are cases that can work.

It works if you allocate the memory in heap within the function, then what the function malloc() Generate pointer you return in the function and everything works. This is not ideal because you will have to release this memory at some point and the ideal is to always librate the memory in the same function that you create, and you cannot do this precisely because you need this object to survive longer than the function. Although not ideal in many cases is the best solution. In others what is done is to allocate in the function that will actually consume the text and then release is done right there, so this way you do not need to return anything, you just pass by reference what has already been created.

If you’re going to do it this way you can create just one array of characters in the stack. This doesn’t always work well in all real code cases, but for small applications it may be ideal. As this code abuses it then it should be the correct one to do, allocated the space in the main() and should not return the data in the function, must make this space to use without returning it. When you pass a reference everything that is modified in it will reflect on the variable that was passed. It would be something like this:

void retornaNome(char nome[], char sobrenome[], char nomeFinal[40]) {

I put in the Github for future reference.

And will return nothing, you just manipulate nomeFinal right there.

Note that if you try to return an allocated object in stack of function when it finishes this object becomes invalid and the best that can happen to you is the application break, can happen worse as running looking like you’re right and one day give a mistake you’ll have no idea what it is and you’ll think the computer went crazy when it’s actually just your wrong code.

I could help with some more code but I won’t do it because there are many errors in this code, to do it right I would have to rewrite it completely, there are many things there that is not how it is done in C, for example the use of strlen(), and there are errors of logic as well. Isac’s response gives an idea of how to do it although I think it took an important part of the code, because this seems to be exercise precisely to manipulate the string in hand.

  • 1

    This answer deserved a better question ;)

3

@Maniero has already focused directly on the problem and what concepts to be aware of and how to solve. I’ll focus specifically on your code.

  • Its function retornaNome return a char, so this is not a text but a letter, which is soon one of the errors it gives you in the compilation.
  • setbuf(stdin, 0); is not useful in your code unless you are running the code in an IDE buffering the outputs and inputs like Eclipse.
  • The placement of the terminator after the fgets should be done with the function strcspn who can look for you at the end of the line, \n, or the end of the text.
  • If you’ve ever declared string to the nomeFinal then why not use it in the function that joins the two names? That would be in fact ideal and follows the line of thought dictated by @Maniero

The last detail is: Don’t re-invent the wheel! Unless you’re making an educational code. Although C requires to do a lot of things manually, there are already several functions that do things useful for us. In your case already has the function strcat to concatenate and strcpy to copy:

Your code with these fixes and using the two C functions I mentioned:

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

void juntaNome(char nome[], char sobrenome[], char nomeFinal[]){
    strcpy(nomeFinal, nome); //colocar o nome
    strcat(nomeFinal, " "); //concatenar um espaço
    strcat(nomeFinal, sobrenome); //concatenar o sobrenome
}

int main(void){
    char nome[20], sobrenome[20], nomeFinal[100];

    printf("Digite seu nome: ");
    fgets(nome, 20, stdin);
    nome[strcspn(nome, "\n")] = '\0';

    printf("Digite seu sobrenome: ");
    fgets(sobrenome, 20, stdin);
    sobrenome[strcspn(sobrenome, "\n")] = '\0';

    juntaNome(nome, sobrenome, nomeFinal);
    printf("%s\n", nomeFinal);

    return 0;
}

Watch it work on Ideone

1

In the function you say that the return is a char, but it should be a char pointer as it returns a string As it should be.

   char * retornaNome(char nome[], char sobrenome[]){

   }
  • This is wrong, it doesn’t resolve to do so.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.