Iniciante em C. Dúvidas em String para retornar a última palavra de uma frase/nome

Boa noite, galera. Gostaria de uma forcinha para resolver o seguinte problema de implementar uma função que recebe como parâmetro uma cadeia de caracteres com o nome completo de uma pessoa e retorne um ponteiro com o último nome encontrado.

A função tem que obedecer esse formato: char *ultimo_nome(char *nome_completo).

Meu código ficou mais ou menos assim, de uma forma bem falha. Tenho bastante dificuldade em manipulação de strings. Por favor, me ajudem. Obrigado!!

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

char *ultimo_nome (char *nome_completo){
  int i, j;
  char c;
  int barra = 1;
  int n = strlen(nome_completo);
  for (i=0; nome_completo[i] != '\0'; i++){
    if (nome_completo[i] == ' ')
      barra+=1;
  }
  char *p = (char *)malloc((n/barra) * sizeof(char));
  for (i=(barra-1)*(n/barra), j=0; n>i; i++){
    p[j++] = nome_completo[i];
  }
  return p;
}

int main(void){
  char pal[] = "Rafael de Moura Machado";
  char *res = ultimo_nome(pal);
  printf("%s[]", res);

  return 0;
}

A biblioteca padrão contém a função strrchr que encontra a ultima ocorrencia de um certo caractere, se vc puder usar esta função, o trabalho fica mais simples, veja:

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

char *ultimo_nome(const char *nome_completo) {
  return strrchr(nome_completo, ' ') + 1;
}

char *ultimo_nome_v2(const char *nome_completo) {
  const char *ultimo = strrchr(nome_completo, ' ') + 1;
  const size_t len = strlen(ultimo) + 1;
  char *ultimoCopia = malloc(len);
  strncpy(ultimoCopia, ultimo, len);
  return ultimoCopia;
}

char *ultimo_nome_v3(const char *nome_completo) {
  size_t len = strlen(nome_completo);
  int index = -1;

  while (len--) {
    if (nome_completo[len] == ' ') {
      index = len + 1;
      break;
    }
  }

  if (index > 0) {
    const char *ultimo = nome_completo + index;
    const size_t len = strlen(ultimo) + 1;
    char *ultimoCopia = malloc(len);
    strncpy(ultimoCopia, ultimo, len);
    return ultimoCopia;
  }

  return "";
}

int main(void) {
  char nome[] = "Rafael de Moura Machado";
  char *resultado1 = ultimo_nome(nome);
  char *resultado2 = ultimo_nome_v2(nome);
  char *resultado3 = ultimo_nome_v3(nome);
  printf("%s\n", resultado1);
  printf("%s\n", resultado2);
  printf("%s\n", resultado3);
  free(resultado2);
  free(resultado3);
  return 0;
}

Dependendo do que vc quer fazer com o sobrenome, não seria necessário alocar memoria para ele, só se vc quiser altera-lo de alguma forma.

Se vc não for modificá-lo, a primeira função do código acima já é o suficiente, senão, vc pode usar a “versão 2” que faz uma cópia, mas vc tem que se lembrar de invocar a função free, hein!

E, se vc não pudar usar a strrchr, a “versão 3” mostra uma possivel forma de se fazer.

1 curtida

A segunda opção é encaixa perfeito para o meu exercício, mas muito obrigado pela variedade de opções que eu poderia usar. Vai ficar como estudo. Muito obrigado. Um abraço!!

1 curtida