Ir para o conteúdo
riqu3s

Remover caracteres que não sejam letras e espaços

Mensagens Recomendadas

riqu3s

Boas pessoal, tenho o seguinte problema: 

Citação

Desenvolva um programa que leia uma frase introduzida pelo utilizador e lhe retire todos os caracteres que não sejam letras nem espaços. No final o programa deverá mostrar a frase atualizada. Exemplos de execução:

Introduza uma frase: 0p.rogra5%mac9ao1./4

Frase com apenas letras e espacos: programacao

Queria que me ajudassem a tentar descobrir como é que removo os tais caracteres da string

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
riqu3s
21 horas atrás, HappyHippyHippo disse:

o problema é "remover" ou detectar ?

o problema é remover os caracteres que não interessam, mostrando só a palavra programação sem o "lixo"

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Rui Carlos

Para remover o caracter numa posição de uma string, podes simplesmente ir a cada um dos caracteres seguintes, e movê-los um posição para trás.  Deverás fazer isto do início para o fim, e deverás copiar também o \0 final.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

O problema é só ler a frase e apresentar o resultado? Não existe a necessidade de guardar a frase tanto na memória inicial ou numa secundária, certo? 


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Rui Carlos
11 minutos atrás, HappyHippyHippo disse:

O problema é só ler a frase e apresentar o resultado? Não existe a necessidade de guardar a frase tanto na memória inicial ou numa secundária, certo? 

Tendo em conta o enunciado, diria que há.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo
3 minutes ago, Rui Carlos said:

Tendo em conta o enunciado, diria que há.

Pelo contrário... Pelo enunciado que apresentaste, só necessitas de guardar o que o utilizador escreveu e fazer o parse directo para a consola. Tens a certeza que o que escreveste é exactamente o que tens no enunciado? 


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
riqu3s
14 minutos atrás, HappyHippyHippo disse:

Pelo contrário... Pelo enunciado que apresentaste, só necessitas de guardar o que o utilizador escreveu e fazer o parse directo para a consola. Tens a certeza que o que escreveste é exactamente o que tens no enunciado? 

Sim tudo aquilo que está no enunciado é aquilo que apareceu num exame

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Rui Carlos
16 minutos atrás, HappyHippyHippo disse:

Pelo contrário... Pelo enunciado que apresentaste, só necessitas de guardar o que o utilizador escreveu e fazer o parse directo para a consola. Tens a certeza que o que escreveste é exactamente o que tens no enunciado? 

O enunciado fala em remover os caracteres, e depois ("no final") em mostrar o resultado.  Por isso diria que ignorar os caracteres ao imprimir não faz o que se pede no enunciado.

Para mim uma solução num teste que não apresentasse um procedimento dedicado a remover os caracteres não teria a cotação toda.  Uma solução que só removesse na impressão provavelmente não teria metade, por muito inteligente que a solução seja.  Por vezes os enunciados nem são suficientemente específicos para permitir descartar soluções menos "completas", mas acho que nem é o caso.  (Mas isto sou eu, que não acho que os alunos deviam desde cedo aprender a separar computação da interacção com o utilizador.)

Em todo o caso, diria que "guardar o que o utilizador escreveu" já implica guardar a frase em memória, não?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
riqu3s
2 horas atrás, Rui Carlos disse:

O enunciado fala em remover os caracteres, e depois ("no final") em mostrar o resultado.  Por isso diria que ignorar os caracteres ao imprimir não faz o que se pede no enunciado.

Para mim uma solução num teste que não apresentasse um procedimento dedicado a remover os caracteres não teria a cotação toda.  Uma solução que só removesse na impressão provavelmente não teria metade, por muito inteligente que a solução seja.  Por vezes os enunciados nem são suficientemente específicos para permitir descartar soluções menos "completas", mas acho que nem é o caso.  (Mas isto sou eu, que não acho que os alunos deviam desde cedo aprender a separar computação da interacção com o utilizador.)

Em todo o caso, diria que "guardar o que o utilizador escreveu" já implica guardar a frase em memória, não?

Outro exemplo de outro exercício que achei parecido com este: 

Desenvolva um programa que leia uma frase e uma palavra introduzidas pelo utilizador, e apresente a frase introduzida sem a primeira ocorrência da palavra, caso exista. Uma frase é um conjunto de palavras separadas por um ou mais espaços. O programa deve ser indiferente a letras minúsculas ou maiúsculas.

Exemplo de execução 1:

Frase: Todos˽juntos˽por˽uma˽causa

Palavra: juntos Resultado: Todos˽˽por˽uma˽causa

 

Exemplo de execução 2:

Frase: Sorrir˽ou˽não˽sorrir!

Palavra: sorrir Resultado: ˽ou˽não˽sorrir!

 

 

O caracter ‘˽’ presente nos exemplos de execução representa um espaço em branco

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Rui Carlos

Antes de passares para outro exercício, já conseguiste resolver o anterior?

O @HappyHippyHippo são sugeriu uma solução simples para o problema (que não é propriamente a que eu recomendaria :D), e também já te indiquei o algoritmo naive para remover caracteres de uma string.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
riqu3s
50 minutos atrás, Rui Carlos disse:

Antes de passares para outro exercício, já conseguiste resolver o anterior?

O @HappyHippyHippo são sugeriu uma solução simples para o problema (que não é propriamente a que eu recomendaria :D), e também já te indiquei o algoritmo naive para remover caracteres de uma string.

Ainda não sou um pro nisto, nem perto disso xD, será que podias explicar de uma forma mais simples esse tal algoritmo "naive"?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Rui Carlos

Sabes fazer um ciclo que percorre todo um array, do início para o fim, e para cada posição i, coloca lá o valor da posição i+1?  (Se a resposta for não, então podes começar por ver isto.)

O passo seguinte é em vez de começares do início, começares numa posição que tenha um carácter que queiras remover.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Inacabado

Muito boa tarde. desculpem meter-me na discussão, até porque é um programa que tambem teria interesse em saber resolver. Nao se poderia guardar a a frase so com letras do alfabeto numa substring da string/problema inicial? Teoricamente pode-se fazer muita coisa,dirão....

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

o que na realidade é então para fazer será (limitando o tamanho dos dados e entrada para tornar as coisas mais simples) :

- ler os dados do utilizador para um buffer qualquer

- criar um segundo buffer do mesmo tamanho do primeiro

- iterar por todas os caracteres do primeiro buffer, e inserir no segundo caso for um caracter aceito (existe já funções para essa verificação ...)

- não esquecer de sinalizar o fim da segunda string com o caracter '\0'

- apresentar o segundo buffer como a solução pretendida

 

Editado por HappyHippyHippo

IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Inacabado

Eu fiz este código mas não me está a dar e já dei umas quantas voltas e nada...

Agradecia imenso uma "dica" que me desbloqueasse este problema, obrigado.

/* Faça um programa que retira de uma string introduzida todos os caracteres que nao sejam 
alfabeto e apresente a nova string*/
#include <stdio.h>
#include <stdbool.h>
#define SIZE 20
	
char *onlyAlpha(char *str)	
{
	char str1[SIZE];
	char *tmp=str1;
	int i;
	bool Alpha=true;
	for(i=0;str[i]!='\0';++i)
	{
		while(Alpha)
		{
			if((str[i]>='A'&& str[i]<='Z')||(str[i]>='a'&& str[i]<='z')||str[i]=='\0')
				str1[i]==str[i];
			else
				Alpha=false;
		}
	}
return 	tmp;
}
int main(void)
{
	int i;
	char str[20];
	
	printf("Introduza uma string: "); gets(str);
	onlyAlpha(str);	
	printf("String só com letras: %s.\n",str);
return 0;
}

Este código tem um comportamento inesperado e não encontro o erro!

No entretanto vou continuar a tentar investigar melhor o que se passa...

Abraço a todos.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Inacabado

Codigo alterado, este é o ultimo mas o problema persiste:

/* Faça um programa que retira de uma string introduzida todos os caracteres que nao sejam 
alfabeto e apresente a nova string*/
#include <stdio.h>
#include <stdbool.h>
#define SIZE 20
	
char *onlyAlpha(char *str)	
{
	char str1[SIZE];
	char *tmp=str1;
	int i;
	bool Alpha=true;
	for(i=0;str[i]!='\0';i++)
	{
		while(Alpha)
		{
			if((str[i]>='A'&& str[i]<='Z')||(str[i]>='a'&& str[i]<='z')||str[i]=='\0')
				str1[i]=str[i]; /*alterado o == por =*/
			else
				Alpha=false;
		}
	}
	str1[i]='\0';/*acrescentado*/
return 	tmp;
}
int main(void)
{
	int i;
	char str[20];
	
	printf("Introduza uma string: "); gets(str);
	char *ptr=onlyAlpha(str);/*acrescentei o ponteiro *ptr*/	
	printf("String só com letras: \n");
	puts(ptr);/*acrescentado*/
return 0;
}

 

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

assim de repente, vejo três grandes problemas:

- o mais simples de perceber é que no teu ciclo de popular o segundo array só com os caracteres "alpha", quando a variável "Alpha" toma o valor de falso, nunca mais volta a ser verdadeiro, logo nunca irás copiar os caracteres após um caracter descartado

- nesse mesmo ciclo, estás a copiar do array original para o segundo array, para a mesma posição, no entanto, se já descartaste um caracter, quer dizer que a posição final não é a mesma, pois não ?

- existe um erro muito grave, mas de mais difícil compreensão. o que a tua função retorna, é a posição de memória de um bloco reservado dentro da função, que no fim desta, deixa de "existir". Por outras palavras, estás a retornar algo que dentro de momentos (após o retorno) pode ou não estar na posição retornada. a maneira mais simples é teres a função main a instanciar os dois arrays e a função fazer só o trabalho de filtragem e cópia para o segundo array,

  • Voto 2

IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Inacabado

Ora aqui está (continua com comportamento estranho...), com as alterações que compreendi dos esclarecimentos dados pelo HHH.

O código:

#include <stdio.h>
#include <stdbool.h>
#define SIZE 20
	
char *onlyAlpha(char *str,char *str1)	
{
	char *tmp=str1;
	int i,j;
	bool Alpha;
	for(i=j=0;str[i]!='\0';i++,j++)
	{
      	Alpha=true;/*acrescentado*/
		while(Alpha)
		{
			if((str[i]>='A'&& str[i]<='Z')||(str[i]>='a'&& str[i]<='z')||str[i]=='\0')
				str1[j]=str[i];
			else
			{
				Alpha=false;/*acrescentado*/
				j--;/*acrescentado*/
			}
		}
	}
	str1[j]='\0';
return 	str1=tmp; /*devolve o endereço inicial the str1*/
}
int main(void)
{
	int i;
	char str[SIZE],str1[SIZE];/*acrescentado o novo array str1 na função main()*/
	
	printf("Introduza uma string: "); gets(str);
	onlyAlpha(str,str1);/*envio dos dois arrays a função onlyAlpha*/	
	printf("String só com letras: \n");
	puts(str1);
return 0;
}

 

Editado por Inacabado

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

vais fazer esta brincadeira : tenta imprimir o valor de "j" em cada iteração dos teus ciclos

  • Voto 1

IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Inacabado
3 horas atrás, HappyHippyHippo disse:

vais fazer esta brincadeira : tenta imprimir o valor de "j" em cada iteração dos teus ciclos

Sinceramente não percebo onde quer chegar...

Se eu colocar:

 for(i=j=0;str[i]!='\0';i++,j++)
        {
                printf("%d\n",j);
                Alpha=true;
(...)

...ele dá o valor de 0 e não continua... O que quererá dizer com isso? Não faço ideia...

Editado por Inacabado

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Inacabado
/* Faça um programa que retira de uma string introduzida todos os caracteres que nao sejam 
alfabeto e apresente a nova string*/
#include <stdio.h>
#include <stdbool.h>
#define SIZE 20
	
char *onlyAlpha(char *str,char *str1)	
{
	char *tmp=str1;
	int i,j;
	bool Alpha;
	for(i=j=0;str[i]!='\0';i++,j++)
	{          
		Alpha=true;
		while(Alpha)
		{
			if((str[i]>='A'&& str[i]<='Z')||(str[i]>='a'&& str[i]<='z')||str[i]=='\0')
			{
				str1[j]=str[i];
				Alpha=false;/*então e este para sair do while, rapaz!???!! Era o que faltava!!!*/
			}
			else
			{
				Alpha=false;
				j--;
			}
		}
	}
	str1[j]='\0';
return 	str1=tmp; /*devolve o endereço inicial the str1*/
}
int main(void)
{
	int i;
	char str[SIZE],str1[SIZE];
	char *ptr=NULL;	
	printf("Introduza uma string: "); gets(str);
	ptr=onlyAlpha(str,str1);	
	printf("String só com letras: \n");
	puts(ptr);
return 0;
}

Oh YESSS! Já deu! Cheguei lá mesmo quando estava para desistir...YES!

  • Voto 1

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

se funciona, não deixa de ser uma solução.

no entanto, existe ai algumas coisas desnecessárias :

#include <stdio.h>
#include <ctype.h>

#define BUFFER_SIZE 256

int main(int argc, char ** argv) {
    char original[BUFFER_SIZE] = {0},
         parsed[BUFFER_SIZE] = {0};

    fgets(original, BUFFER_SIZE, stdin);
    for (int i = 0, j = 0; original[i]; ++i)
        if (isalpha(original[i]))
            parsed[j++] = original[i];

    printf("parsed  %s\n", parsed);
}

 

  • Voto 1

IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.