Jump to content

Retornar string de uma função


BrunoT
 Share

Recommended Posts

Boas pessoal !

Vou tentar explicar o que se passa, mas antes disso vou copiar as partes do código que interessa

typedef struct sEquipa {
char nome[20];
char pais[20];
int nCc;
struct sEquipa *seg;
} Equipa, *lEquipa;

typedef struct sCiclista {
char nome[20];
int idade;
char nac[20];
int dorsal;
char equipa[20];
int tEtapas;
int pEtapas;
int pMont;
int etaPer;
struct sCiclista *seg;
} Ciclista, *lCiclista;

char* retEquipa (lEquipa l3, int opc) {

int cont =1;

	while ( l3!= NULL ) {

		if ( opc == cont ) return l3->nome;
		else { 
			l3 = l3->seg;
			cont++;
		}
	}

return NULL;

}

b->equipa = retEquipa (l3,equip);

O que queria é que a função retEquipa retornasse o nome da equipa para adicionar a estrutura do ciclista. Alguém me pode ajudar ?

Deixem-me também dizer que o b é do tipo apontador para Ciclista ...

Cumprimentos

Bruno Araújo

Link to comment
Share on other sites

Vou tentar estruturar isto o máximo possível.

Tu sabes que:

- O nome de uma string é na verdade um ponteiro para o seu 1º elemento.

- Quando uma função termina todas as variáveis "pertencentes" à função são destruídas. (stack frame da função)

Seguindo esta teoria tu ao declarares uma string local, quando a função terminar o seu "conteúdo" vai ser destruído, como o nome da string é um ponteiro para o seu primeiro elemento tu ao fazeres return (literalmente) desse ponteiro vais estar a retornar o endereço de algo que já foi destruído (visto que a função já terminou), então vais ter com o velho amigo "segmentation fault".

Agora que já percebeste a teoria, percebes que não podes retornar (literalmente) uma string.

Para solucionares este problema tens duas opções:

- Declaras a string como global (isto não se costuma fazer).

- Declaras um ponteiro do tipo char * e alocas dinamicamente uma string.

Aconselho-te a seguires a 2ª opção, depois basta retornares o endereço e recebê-lo com um ponteiro.

Só para terminar o post, lembra-te que alocando dinamicamente o que alocaste só vai ser destruído quando tu quiseres (tipicamente com função free), ou seja, podes sempre trabalhar com um ponteiro. Para alocares utiliza por exemplo, a função malloc. 

here since 2009

Link to comment
Share on other sites

Dei-te duas maneiras de como resolver esse problema, agora é só aplicares. Pelo que vi do código já tens conhecimentos em ponteiros, portanto é só alocares e depois trabalhares com o ponteiro que recebe o endereço.

Já agora deixo aqui um exemplo:

char *heap = (char *)malloc(sizeof(char) * N);
return heap;

Neste caso, heap será o ponteiro que vai receber o endereço. Estamos a alocar uma string com N caracteres.

here since 2009

Link to comment
Share on other sites

- O nome de uma string é na verdade um ponteiro para o seu 1º elemento.

- Quando uma função termina todas as variáveis "pertencentes" à função são destruídas. (stack frame da função)

Seguindo esta teoria tu ao declarares uma string local, quando a função terminar o seu "conteúdo" vai ser destruído, como o nome da string é um ponteiro para o seu primeiro elemento tu ao fazeres return (literalmente) desse ponteiro vais estar a retornar o endereço de algo que já foi destruído (visto que a função já terminou), então vais ter com o velho amigo "segmentation fault".

A teoria está bem. Só que não se aplica a este caso, e acabaste por matar uma mosca com um míssil, e o código continua a não funcionar porque está-se a tentar atribuir o valor de um apontador a um array na última linha de código apresentada.

sCiclista e sEquipa são nós de listas simplesmente ligadas. Ao retornar l3->nome, não é o endereço de uma variável local que vai ser retornado, é o valor de um apontador que existe num desses nós, o qual continua a ser válido após a função terminar.

A única alteração que vejo ser necessária é substituir a tal última linha por um strcpy, copiando o resultado da chamada à função retEquipa para o campo b->equipa.

Já agora, uma sugestão que não sei se podes seguir: em vez de teres o nome da equipa como um array de caracteres em sCiclista, não podes ter antes um apontador para sEquipa? Evitavas andar a copiar strings, e tinhas a informação de equipa toda "agarrada" ao ciclista.

Desaparecido.

Link to comment
Share on other sites

Obrigado aos dois, desde já.

Realmente o que eu tava a fazer era uma autêntica estupidez, o que tinha feito estava certo, só precisava de fazer

strcpy (retEquipa (l3,equip),b->equipa);

Uma distracção :s

Quanto à ultima sugestão do The Dark ... é realmente uma boa ideia que melhoraria a perfomance, vai já directo para a lista de optimizações.

Mais uma vez, obrigado aos dois.

Link to comment
Share on other sites

Claro, tinha que a minha distracção entrar ao serviço. 😄

Já agora, isto é um trabalho para a universidade ... acham que depois de entregue e avaliado, é útil postar o programa aqui no forum ? Ou não é aconselhável ?

Cumprimentos

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.