Exercício em C

1. Exercício em C

Geovani Leite
GeovaniLeite

(usa Outra)

Enviado em 24/06/2017 - 16:18h

Boa tarde! Recentemente criei um tópico sobre um exercício em C que não conseguia resolver, porém agora consegui com a ajuda dos amigos da comunidade.
O algoritmo consiste em ler um nome e imprimi-lo como uma referência. Exemplo:

Entrada: Armando Luiz Nicolini Delgado.
Saída: DELGADO, Armando Luiz Nicolini.

O algoritmo está funcionando, porém quando imprimi o nome, aparece alguns símbolos antes. (como: @ DELGADO, Armando Luiz Nicolini)

#include<stdio.h>
#include<locale.h>
#include<string.h>
#include<ctype.h>
//Aluno: Geovani Leite

int main(){

setlocale(LC_ALL, "Portuguese");

char nome[100],sobrenome[20];
int i,j,aux;

printf("Digite um nome: ");
scanf("%[A-Za-z 0-9]",nome);

i=strlen(nome);
j=0;
while(nome[i] != ' '){
sobrenome[j]=nome[i-1];
i--;
j++;
}
aux = i;
for(i=strlen(sobrenome);i>=0;i--){
sobrenome[i]=toupper(sobrenome[i]);
}

for(i=strlen(sobrenome);i>0;i--){
printf("%c",sobrenome[i-1]);
}
printf(", ");
for(i=0;i<aux;i++){
printf("%c",nome[i]);
}
printf(".\n");

return 0;
}


Agradeço se alguém ajudar a remover esses símbolos



  


2. Re: Exercício em C

Paulo
paulo1205

(usa Ubuntu)

Enviado em 24/06/2017 - 20:03h

Em nenhum momento você colocou o byte nulo terminador da string em sobrenome(). Assim sendo, o uso que você faz de strlen(sobrenome) terá comportamento indefinido.

Na prática, o lixo que aparece antes é justamente por causa da falta desse terminador. Você monta o sobrenome de trás para diante no array. No caso do exemplo que você mostrou, em que o último nome é “Delgado”, você vai ficar com os sete primeiros bytes, de sobrenome[0] até sobrenome[6], iguais a "ODAGLED". O oitavo byte teria de ser um byte nulo, para que strlen(sobrenome) desse 7 como resposta, que é o número de letras nesse sobrenome. Mas você não põe esse byte nulo lá em momento nenhum.

Da oitava posição em diante, portanto, o que você tem é indeterminado, e isso fará com que strlen(sobrenome) possa devolver um valor maior do que 7. Como você imprime os caracteres do fim para o início, onde esse fim é o valor do comprimento de sobrenome você pode acabar imprimindo primeiro os caracteres que estão além da sétima posição.

---

Como comentário adicional, depois que você consertar a falta do terminador, você não varrer sobrenome duas vezes. Você já pode chamar toupper() diretamente na hora de imprimir.


3. Re: Exercício em C

Paulo
paulo1205

(usa Ubuntu)

Enviado em 24/06/2017 - 20:28h

Outra coisa. Como seu programa se porta se a pessoa tiver apenas um nome? Se você quisesse incluir “Platão” ou “Aristóteles” entre suas referências, conseguiria?

(E não falo nem por causa dos acentos, que é outro problema, mas porque, numa olhada rápida, não me pareceu que você trate o caso de não encontrar um espaço na string contendo o nome completo.)


4. Re: Exercício em C

Perfil removido
removido

(usa Nenhuma)

Enviado em 24/06/2017 - 20:50h

paulo1205 escreveu:

Em nenhum momento você colocou o byte nulo terminador da string em sobrenome(). Assim sendo, o uso que você faz de strlen(sobrenome) terá comportamento indefinido.

Na prática, o lixo que aparece antes é justamente por causa da falta desse terminador. Você monta o sobrenome de trás para diante no array. No caso do exemplo que você mostrou, em que o último nome é “Delgado”, você vai ficar com os sete primeiros bytes, de sobrenome[0] até sobrenome[6], iguais a "ODAGLED". O oitavo byte teria de ser um byte nulo, para que strlen(sobrenome) desse 7 como resposta, que é o número de letras nesse sobrenome. Mas você não põe esse byte nulo lá em momento nenhum.

Da oitava posição em diante, portanto, o que você tem é indeterminado, e isso fará com que strlen(sobrenome) possa devolver um valor maior do que 7. Como você imprime os caracteres do fim para o início, onde esse fim é o valor do comprimento de sobrenome você pode acabar imprimindo primeiro os caracteres que estão além da sétima posição.

---

Como comentário adicional, depois que você consertar a falta do terminador, você não varrer sobrenome duas vezes. Você já pode chamar toupper() diretamente na hora de imprimir.


Cara aonde você aprende C++, é livro ou material na internet mesmo?

Você é um mito do cacete em C++ enquanto eu tô aprendendo Python kkk.








Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts