paulo1205
(usa Ubuntu)
Enviado em 26/06/2017 - 13:39h
Como você já marcou o tópico como resolvido, segue uma versão que varre a string com o nome completo apenas uma vez (logo não usa
strlen (), que contaria como uma varredura), do início para o final, e vai marcando posições interessantes através de ponteiros para dentro do nome completo. Ela sabe tratar monônimos (como “Moisés”, “Isaías”, “Lucas”, “Platão” ou “Voltaire”), e não altera a string inicial nem copia caracteres para outras variáveis ou para funções, exceto na hora de os imprimir.
Variáveis interessantes:
-
p : ponteiro usado para precorrer a string;
-
p_first_name : ponteiro para o início do primeiro nome (se for antecedido por espaços, esses espaços são descartados).
-
p_space_before_last : ponteiro para o primeiro espaço antes do último nome (indica onde parar de imprimir os nomes que antecedem o último);
-
p_last_name : ponteiro para o início do último nome;
-
p_after_last : ponteiro para a posição após o fim do último nome.
#include <ctype.h>
#include <stdio.h>
void print_reference(const char *full_name){
const char *p;
const char *p_first_name, *p_last_name;
const char *p_space_before_last, *p_after_last;
p_first_name=p_space_before_last=NULL;
// Descarta espaços antes do primeiro nome, se existirem.
for(p=full_name; *p && !p_first_name; ++p)
if(isspace(*p)){
if(!p_space_before_last)
p_space_before_last=p;
}
else
p_first_name=p;
// Neste ponto, p_first_name aponta para o primeiro nome, depois de
// pulados eventuais espaços.
// Como o nome pode ser um monônimo, supõe, por enquanto, que
// o primeiro nome é também o último.
p_last_name=p_first_name;
p_after_last=NULL;
// Verifica se existem outros nomes além do primeiro.
for(; *p; ++p)
if(isspace(*p)){
if(!p_after_last || p_after_last<p_last_name)
p_after_last=p;
}
else if(p_after_last && p_last_name<p_after_last){
p_space_before_last=p_after_last;
p_last_name=p;
}
// p_after_last indica onde termina o último nome. Se for um espaço
// (i.e. os últimos caracteres da string são espaços em branco), já
// foi definido no laço de repetição acima. Contudo, se for o fim da
// string, faz com que aponte para esse fim.
if(!p_after_last || p_after_last<p_last_name)
p_after_last=p;
// Encontrou o último nome?
if(p_last_name){
// Imprime o último nome um caráter por vez, convertido em maiúsculo.
for(p=p_last_name; p<p_after_last; ++p)
putchar(toupper((unsigned char)*p));
// Se tiver mais de um nome, imprime apenas os nomes iniciais, usando
// o recurso de limitar a quantidade de caracteres na string de
// formatação da função printf().
if(p_first_name!=p_last_name)
printf(", %.*s", (int)(p_space_before_last-p_first_name), p_first_name);
putchar('\n');
}
}