Exercício em C

1. Exercício em C

Geovani Leite
GeovaniLeite

(usa Outra)

Enviado em 01/07/2017 - 20:15h

Boa noite. Tenho um exercício pra resolver onde tenho que buscar quantas vezes uma palavra aparece dentro de uma frase, porém a última palavra só está contando quando tem o ponto final.

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

int main(){

setlocale(LC_ALL, "Portuguese");

char frase[500], palavra[10];
int i, j=0, cont=0, tamPalavra;

printf("\nFrase (com ponto final): ");
scanf("%[^\n]s", frase);
printf("Palavra: ");
scanf(" %[^\n]s", palavra);

if(strlen(palavra) <= 10){

tamPalavra = strlen(palavra);

for (i = 0;frase[i] != '\0';){ //enquanto for diferente de nulo
if (frase[i] == ' '){ //se for espaço
i++;
}
else{ //se não for espaço
if (frase[i] == palavra[j]){ //vê se é igual
j++; //acrescenta j
i++; //acrescenta i
}
else if (j == tamPalavra){ //senao, se j for igual ao tamanho da palavra
j = 0; //j recebe 0,
cont++;

}
else{
i++;
j = 0;
}
}
}
printf("A palavra [%s] aparece %d vezes na frase.\n",palavra,cont);
}else{
printf("\nA palavra deve ter no máximo 10 letras.\n");
}

return 0;
}



  


2. Re: Exercício em C

Paulo
paulo1205

(usa Ubuntu)

Enviado em 02/07/2017 - 06:04h

Alguns problemas e algumas sugestões:

1) Declaração de main(). Em C, se você não quiser passar nenhum argumento do sistema operacional para o programa, você deve declarar main() assim:
int main(void) 


2) Por que a frase tem de ter um ponto final? Tudo bem que, gramaticalmente, o certo é ter um sinal de pontuação no final da frase. Mas por que não pode ser uma pergunta, ou uma exclamação? Cuidado para não criar uma regra que não esteja no enunciado apenas para compensar uma deficiência do algoritmo.

3) As strings de formatação de scanf() estão erradas. Você não deve colocar o caráter “s” após fechar os colchetes, a não ser que esteja realmente esperando que haja um “s” nessa posição. Garanto a você que esse nunca será o caso, pois o que você quer mesmo é que haja um '\n' nessa posição.

4) Você deveria colocar limites nos tamanhos máximos das strings lidas na própria string de formatação. Fazendo isso, você vai garantir que suas strings serão válidas.
char frase[500], palavra[40];
/* ... */
// 499 é igual a 500 (espaço declarado) menos 1 (byte reservado para o terminador da string).
if(scanf(" %499[^\n]", frase)!=1){
fprintf(stderr, "Erro ao ler a frase.\n");
exit(1);
}
/* ... */
// 39 é igual a 40 (espaço declarado) menos 1 (byte reservado para o terminador da string).
if(scanf(" %39[^\n]", palavra)!=1){
fprintf(stderr, "Erro ao ler a palavra.\n");
exit(1);
}


5) Se você usar a formatação mostrada acima, indicando o tamanho máximo a ser lido, vai poder remover aquele teste do tamanho da string (aliás, aquele teste está errado, pois o limite de tamanho está maior do que a maior string válida possível).

6) Você não precisa usar strlen() em lugar nenhum do seu programa.

7) Ao varrer a frase procurando a palavra, i pode sempre crescer, incondicionalmente, como num loop normal (i.e. algo como “for(i=0; frase[i]; i++)”). Tire os incrementos de dentro de cada braço de if/else, pois acaba sendo redundante tê-lo em vários lugares.

8) Possivelmente seria mais interessante ter um ponteiro como variável de controle (e.g. “for(char *p=frase; *p; p++)”, e trocando todas as ocorrências de “frase[i]” por “*p”). Análogo vale para j (i.e. “palavra[j]” poderia ser trocado por “*q”, “j=0” se tornaria “q=palavra”, e “j++” passaria a ser “q++”).

9) Você tem de repensar todos os casos em que deve zerar o valor de j (ou resetar o ponteiro, caso opte pela troca sugerida acima).


3. RE: Exercício em C

Geovani Leite
GeovaniLeite

(usa Outra)

Enviado em 03/07/2017 - 10:01h

paulo1205 escreveu:

Alguns problemas e algumas sugestões:

1) Declaração de main(). Em C, se você não quiser passar nenhum argumento do sistema operacional para o programa, você deve declarar main() assim:
int main(void) 


2) Por que a frase tem de ter um ponto final? Tudo bem que, gramaticalmente, o certo é ter um sinal de pontuação no final da frase. Mas por que não pode ser uma pergunta, ou uma exclamação? Cuidado para não criar uma regra que não esteja no enunciado apenas para compensar uma deficiência do algoritmo.

3) As strings de formatação de scanf() estão erradas. Você não deve colocar o caráter “s” após fechar os colchetes, a não ser que esteja realmente esperando que haja um “s” nessa posição. Garanto a você que esse nunca será o caso, pois o que você quer mesmo é que haja um '\n' nessa posição.

4) Você deveria colocar limites nos tamanhos máximos das strings lidas na própria string de formatação. Fazendo isso, você vai garantir que suas strings serão válidas.
char frase[500], palavra[40];
/* ... */
// 499 é igual a 500 (espaço declarado) menos 1 (byte reservado para o terminador da string).
if(scanf(" %499[^\n]", frase)!=1){
fprintf(stderr, "Erro ao ler a frase.\n");
exit(1);
}
/* ... */
// 39 é igual a 40 (espaço declarado) menos 1 (byte reservado para o terminador da string).
if(scanf(" %39[^\n]", palavra)!=1){
fprintf(stderr, "Erro ao ler a palavra.\n");
exit(1);
}


5) Se você usar a formatação mostrada acima, indicando o tamanho máximo a ser lido, vai poder remover aquele teste do tamanho da string (aliás, aquele teste está errado, pois o limite de tamanho está maior do que a maior string válida possível).

6) Você não precisa usar strlen() em lugar nenhum do seu programa.

7) Ao varrer a frase procurando a palavra, i pode sempre crescer, incondicionalmente, como num loop normal (i.e. algo como “for(i=0; frase[i]; i++)”). Tire os incrementos de dentro de cada braço de if/else, pois acaba sendo redundante tê-lo em vários lugares.

8) Possivelmente seria mais interessante ter um ponteiro como variável de controle (e.g. “for(char *p=frase; *p; p++)”, e trocando todas as ocorrências de “frase[i]” por “*p”). Análogo vale para j (i.e. “palavra[j]” poderia ser trocado por “*q”, “j=0” se tornaria “q=palavra”, e “j++” passaria a ser “q++”).

9) Você tem de repensar todos os casos em que deve zerar o valor de j (ou resetar o ponteiro, caso opte pela troca sugerida acima).




Muito obrigado pelas suas dicas. Eu sou iniciante em C e ainda não manjo muito bem.




4. Re: Exercício em C

Paulo
paulo1205

(usa Ubuntu)

Enviado em 03/07/2017 - 16:54h

Meu intuito é ajudá-lo a aprender. Quando eu aponto problemas no código, minha intenção é de que você ganhe conhecimento ao corrigi-los.

Mas eu nem sempre posso ser muito direto com a ajuda. Num caso como o de corrigir a maneira de usar a conversão "%"[, eu posso mostrar como fazer (até porque você provavelmente foi ensinado do modo errado, então a intervenção direta é para corrigir outra intervenção direta). Noutras situações, qualquer intervenção direta seria entregar a resposta da questão pronta (ou boa parte dela), de modo que eu tenho de dizer apenas coisas vagas (como quando eu disse que você não precisa de strlen()).

Se você tiver dúvidas mais pontuais, pode trazê-las. Geralmente as respostas a esse tipo de dúvidas podem ser uma resposta mais direta.






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts