• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Ribamar

Programa que escreva o texto lido do standard input

13 mensagens neste tópico

Boas.

A ideia é fazer um "programa que escreva o texto lido do standard input, com getchar(), excepto os espaços no final de cada linha e as linhas em branco."

Tendo em conta qu o tamanho e numero de linhas é variavel não posso usar memoria estatica nem dinamica. Tenho de guardar as linhas ligas pelo getchar() num ficheiro.

É a unica hipote que tenho não é?

Estou a pensar primeiro o programa criar o ficheiro de texto com as linhas lidas e depois correr esse ficheiro e apresentar as linhas pretendidas no standard output. Mas vejo nisso um problema.

Imaginemos que na primeira vez que o programa corre sao escritas 10 linhas. Guarda no ficheiro as 10 linhas, depois imprime as que estao dentro dos parametros pretendidos. Fecho o programa. Executo de novo o programa e são lidas 5 linhas. Como o ficheiro da 1ª vez já tinha guardado 10 linhas, apesar de na segunda vez so ler 5 linhas o ficheiro vai ter na mesma 10 linhas, 5 linhas da nova execução, mais as 5 linhas que ficam no resto do ficheiro da primeira execução correcto? Como dou volta a isso?

cumps

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu não gosto da tua ideia de usar um ficheiro temporário para guardar as linhas ... mas se abrires o ficheiro com o modo "w" ele é limpo.

f = fopen("ficheiro_temporario", "w");
fclose(f);
/* se não houve erros, o ficheiro "ficheiro_temporario" está com 0 bytes */

A maneira que eu faria isso seria escrever todos os caracteres que não fossem espaço um a um à medida que os fosse lendo; e actualizava um contador de caracteres.

Se lesse um espaço actualizava um contador de espaços (ao ler um caracter normal, metia o contador de espaços a zero).

Se lesse um "fim de linha" e o contador de caracteres fosse maior ou igual a 1 escrevia o "fim de linha"; metia também os contadores a zero, quer tivesse escrito ou não o "fim de linha".

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

mas da maneira que tas a dizer como escreves a seguinte linha:

"abc      b  a"

tipo, tens de avançar com o getchar sp, lês o 1º espaço e n escreves, avançando com o getchar depois como escreves os espaços que ficaram pa tras?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ahhhhhhh, pois ... faltava essa particularidade :P

Ao ler um caracter normal, antes de escrever esse caracter escrevia tantos espaços quantos o contador de espaços "mandasse" e depois metia o contador de espaços a zero.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Assim de repente, depois desta vergonhosa exibição da selecção, a minha solução é:

int main(){
char c = getchar();
int countSpaces = 0;
while(c != EOF){
	if(c != ' ' && c != '\t') putchar(c);
	else{
		while(c == ' ' || c == '\t'){
			++countSpaces;
			c = getchar();
		}
		if(c == '\n'){putchar(c); goto label1;}
		while(countSpaces > 0){ putchar(' '); --countSpaces;}
		putchar(c);
	}
label1:
	countSpaces = 0;
	c = getchar();

}

tive d recorrer ao goto q bem sei q é de evitar mas aparentemente esta a funcionar para tds os casos

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Parabéns! Agora só falta o teu programa não imprimir linhas em branco :P

EDIT: Com certeza reparaste que o teu programa troca TABs de input em espaços normais.

Numa futura versão do programa talvez queiras converter os TABs em tantos espaços quantos os necessários para atingir a coluna 8, 16, 24, ...

Tenho duas coisas importantes a apontar:

1) Não incluiste o <stdio.h>

Por acaso, neste teu programa não é MUITO importante, mas habitua-te desde pequenino a incluir os headers necessários. Por exemplo, sempre que usares o printf() é MUITO importante incluir o <stdio.h>.

2) Declaraste a variável `c` como char. Ela devia ser int.

A função putchar() recebe um int; a função getchar() devolve um int.

Se o teu compilador considerar `char` como `unsigned char`, o ciclo

while (c != EOF) { /* ... */ }

nunca pára! A variável `c`, se for unsigned char, tem valores entre 0 e (provavelmente) 255 e a valor da macro EOF é um valor negativo do tipo `int`.

Quando o compilador usa `signed char` para o tipo `char`, perdes um caracter normal de input, pois esse caracter é interpretado erradamente como EOF.

~~~~~~~~

Quanto ao goto ... podes por o código que o goto passa por cima dentro dum else.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ya eu tinha-me apercebido dos tabs ficarem espaços.

eu no meu ficheiro c tenho o #include nao te preocupes :P

Percebi essa cena do char por causa do EOF, obg pela dica

so n percebi a ultima cena em que falas do goto...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
so n percebi a ultima cena em que falas do goto...

while(c != EOF){
	if(c != ' ' && c != '\t') putchar(c);
	else{
		while(c == ' ' || c == '\t'){
			++countSpaces;
			c = getchar();
		}
/*			if(c == '\n'){putchar(c); goto label1;} */
		if(c == '\n'){putchar(c);}
/* NEW */		else {
			while(countSpaces > 0){ putchar(' '); --countSpaces;}
			putchar(c);
/* NEW */		}
	}
/* label1: */
	countSpaces = 0;
	c = getchar();

}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Hmm... Isso é PICC? Tens aulas com quem? Aconselho-te vivamente a NUNCA utilizares goto, senão és esfolado vivo na discussão...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ui. Se apareces lá com um goto... bem podemos ter pena de ti! Pode ser que ainda apareças no blog :confused:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

ya lol, ja tirei o goto.

nos ficamos viciados no goto nas cadeiras de lic e ac com os jumps no assembly

0

Partilhar esta mensagem


Link 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