Jump to content

Recommended Posts

Posted (edited)

Comecei a aprender as strings e estava a tentar criar um programa que pedisse ao user uma frase e que em todas as letras acentuadas ou acedilhadas ele colocasse um cardinal... Ou seja;

Lê uma frase

Copia a frase para outra variável para guardar a original

Procura vogais acentuadas

Substitui-as por #'s

Apresenta a frase original e a frase alterada...

O code que tenho é este mas não está a funiconar

#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main (void){
  char frasein [100], fraseout [100];
  int i;
  printf ("Introduza uma frase: ");
  gets (frasein);
  for (i=0; i<strlen (frasein); i++)
	fraseout [i] = frasein [i];
  for (i=0; i< strlen (fraseout); i++)
	switch (tolower (fraseout [i])) {
		   case 'ç':
		   case 'â':
		   case 'ã':
		   case 'á':
		   case 'à':
		   case 'é':
		   case 'è':
		   case 'ê':
		   case 'í':
		   case 'ì':
		   case 'ó':
		   case 'ò':
		   case 'ú':
		   case 'ù':fraseout [i] = '#';
	}
  printf ("Frase original: %s!!!\nFrase final: %s!!!\n", frasein, fraseout);
getchar ();
return 0;
}

O que é que está mal para ele não fazer o pretendido?

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted (edited)

É que com o seguinte código funcionou e com este que criei já não está a dar...

Código que funcionou:

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

int main (void) {
int i, comp;
char frasein [100], fraseout [100];

printf ("Digite uma frase: ");
gets (frasein);
comp = strlen (frasein);

for (i=0; i<comp; i++)
 switch (tolower (frasein [i])) {
  case 'a':
  case 'e':
  case 'i':
  case 'o':
  case 'u': frasein [i] = '#';
}
printf ("Frase digitada: %s\n", frasein);
getchar ();
return 0;
}
Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted

Suponho que as diferenças estejam no charset usado pelo compilador e pelo ambiente de execução do programa.

Executa este programeta para verificar:

#include
int main(void) {
char buffer[100];
printf("Introduz a string 'ãéç':");
fgets(buffer, sizeof buffer, stdin);
printf("input do teclado: %d %d %d\n", buffer[0], buffer[1], buffer[2]);
printf("valores compilados; %d %d %d\n", 'ã', 'é', 'ç');
   return 0;
}

A melhor solução é veres os valores resultantes de teclado para cada letra e usar esses valores nos cases do switch.

Usa o valor directamente

			 case 183: /* ... */

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Posted (edited)

Aqui o #inlcude sem nada à frente dá erro...

Output do teu programa:

Introduz a string 'ãéç':ãéç

input do teclado: -61 -93 -61

valores compilados; 50083 50089 50087

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted

Aqui o #inlcude sem nada à frente dá erro...

Output do teu programa:

Oops, isso foi uma desatenção minha. O meu computador teve um BSOD quando eu estava a escrever o programa; depois do reboot fiz a recuperação da resposta mas falhou o include.

Era suposto ser

#include <stdio.h>

O programa continua a não dar output com o include correcto?

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Posted

O teu dá

Introduz a string 'ãéç':ãéç

input do teclado: -61 -93 -61

valores compilados; 50083 50089 50087

Para explicar melhor...

O programa que está a funcionar bem, foi escrito, compilado e executado num telefone Android (linux based).

O programa que não me está a funcionar foi escrito, compilado e executado num PC com Debian mas estou a aaceder a esse PC através de um PC com Windows XP através do putty...

Não sei se me fiz entender... Será que isto faz diferença?

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted

Então a minha suposição é verdade: o charset de execução e o charset de compilação são diferentes.

Usa os valores obtidos com o charset de execução no código do teu programa:

                           // ...
                          case -61:
                          case -93:
                          case -61:fraseout [i] = '#';

Este problema acontece porque o C básico foi pensado para caracteres ASCII e os caracteres 'ç', 'é', etc não são ASCII. O uso de caracteres que não são ASCII em regras diferentes consoante o ambiente em que estão a ser usadaos.

Por exemplo: no editor o 'ã' tem o valor 50083, no cmd.exe o 'ã' tem o valor -61.

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Posted (edited)

Eu pensei que todos os caracteres tinham um code ASCII igual fosse qual fosse a plataforma em que os programas fossem compilados...

Eu ainda não percebo nada disso dos charsets afectos ao SO ou ao ambiente em que estão a ser ocmpilados (compiladores)...

Mas a prof da cadeira escreveu o tal programa que está a funcionar, em Windows e eu copiei o code para o meu telefone (Android) e funcionou bem!!! Por isso não consig compreender isso... E os profs também não sabem explicar porque eles só estão habituados ao Windows e ao Visual Studio Express e pouco mais...

Eu, em termos de programação, eu só estou habituado praticamente ao Linux, ou seja, GCC e também um pouco ao Code::Blocks no Windows...

PS:

Falas que no editor o 'ã' tem um valor e que no cmd.exe tem outro.

Em que editor falas? cmd.exe presumo que seja windows, certo?

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted

Os caracteres básicos (letras maisuculas e minusculas sem acentos, digitos, muitos sinais de pontuacao) tem o mesmo valor em praticamente todos os computadores existentes actualmente (ASCII).

Para os caracteres fora desse conjunto (letras com acentos, caracteres gregos, caracteres japoneses, simbolos variados, ..., ...) ha muitas maneiras diferentes de os representar numericamente.

Se o teu editor e o teu ambiente de execução representarem os caracteres com o mesmo valor numérico, é mais fácil acertar o que está escrito no código e o que aparece quando se corre o programa; se o editor e o ambiente de execução usam valores numéricos diferentes estás metido numa salganhada diabólica.

Para principiantes (e programas de aprendizagem) é aconselhável ignorar estes problemas e usar somente os caracteres basicos.

Se o assnto te interessa podes ler (pesquisa google) sobre os tópicos DBCS, Unicode, EBCDIC, code page, endianness, ...

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Posted

Voltando a esta questão...

Como faço então para saber a que código corresponde um 'é' ou um 'ç' no meu PC?

Depois de saber esses valores, uso-os no switch, não era isso que querias dizer, pmg?

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted

Escrvi isto a ver se funcionava bem para me retribuir os valores destes caracteres ams não ficou a funcionar muito bem...

Deve ainda ali haver algum problema com o buffer do teclado que não o sei resolver...

#include <stdio.h>
int main (void){
  int i, e;
  char car;
  for (i=1; ; i++){
  printf ("Para sair, digite \'0\'\n");
  scanf ("%d", &e);
  if (e){
	 printf ("Introduza um caracter para avaliar: \n");
	 scanf (" %c", &car);
	 printf ("O caracter inserido %c tem o valor de %d\n", car, (int) car);
  }
  else
	 break;
  }
getchar ();
return 0;
}

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted (edited)

usa o seguinte código para perceber o que se passa e o que deverás fazer

#include <stdio.h>
#include <string.h>
#include <wchar.h>

#define IS_MB_CHAR(a) (a >= 128)
#define IS_MB_CHAR_PT(pt) (*pt >= 128)

const char * to_binary(int x, int size)
{
   static char b[33] = {0};
   int z;

   for (z = size * 8 - 1; z >= 0; z--)
   {
       b[z] = (x & 1) + '0';
       x >>= 1;
   }

   return b;
}

int in_list(unsigned char * c, const char * list)
{
   int length = strlen(list) - 1;
   int i = 0, size = 1;

   if (IS_MB_CHAR_PT(c))
       size = 2;

   for (i = 0; i < length; i++)
       if (memcmp(c, &list[i], size) == 0)
           return 1;

   return 0;
}

int main()
{
   char readed[100] = {0};
   char accents[86] = "áàãâÁÁÃÃéèẽêÉÈẼÊíìĩîÍÌĨÎóòõôÓÒÕÔúùũûÚÙŨÛçÇ";
   int i, pos, is_accent;

   printf("digite a string : ");
   fflush(stdout);
   fgets(readed, 20, stdin);
   readed[strlen(readed) - 1] = 0;
/*
   printf("input : ");
   for (i = 0; readed[i] != 0; i++)
     printf("%s|", to_binary(readed[i], sizeof(char)));
   printf("\n");
*/

   for (i = 0, pos = 0; readed[i] != 0; i++, pos++)
   {
       is_accent = in_list(&readed[i], accents);
       printf("Caracter %2d (%2d=%c) is acentuated : %d\n",
              pos,
              i,
              !is_accent ? readed[i] : '#',
              is_accent);

       if (is_accent)
           i++;
   }

   return 0;
}
Edited by HappyHippyHippo
IRC : sim, é algo que ainda existe >> #p@p
Posted

Um ciclo infinito (que acaba com um break) feito com for é assim

for (; { /* codigo com um break algures */ }

Ja agora, podes fazer um ciclo infinito com while ou do /* ... */ while

while (1) { /* codigo com um break algures */ }

do { /* codigo com um break algures */ } while (1);

~~~~~~~~

Quanto a solucao para o teu problema da identificacao de caracteres, a minha primeira solucao é incompleta (nao funciona para conjuntos de caracteres com multi-byte) e provavelmente nao funciona para ti. Experimenta a sugestao do Hippo.

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Posted

O output do gcc a compilar é:

hippyhippo.c: In function ‘main’:
hippyhippo.c:56:23: warning: pointer targets in passing argument 1 of ‘in_list’ differ in signedness [-Wpointer-sign]
hippyhippo.c:22:5: note: expected ‘unsigned char *’ but argument is of type ‘char *’

O programa deu o seguinte quando executado:

./hippyhippo

digite a string : Os cães apenas são perigosos se os donos forem deveras otários!

Caracter 0 ( 0=O) is acentuated : 0

Caracter 1 ( 1=s) is acentuated : 0

Caracter 2 ( 2= ) is acentuated : 0

Caracter 3 ( 3=c) is acentuated : 0

Caracter 4 ( 4=#) is acentuated : 1

Caracter 5 ( 6=e) is acentuated : 0

Caracter 6 ( 7=s) is acentuated : 0

Caracter 7 ( 8= ) is acentuated : 0

Caracter 8 ( 9=a) is acentuated : 0

Caracter 9 (10=p) is acentuated : 0

Caracter 10 (11=e) is acentuated : 0

Caracter 11 (12=n) is acentuated : 0

Caracter 12 (13=a) is acentuated : 0

Caracter 13 (14=s) is acentuated : 0

Caracter 14 (15= ) is acentuated : 0

Caracter 15 (16=s) is acentuated : 0

Caracter 16 (17=▒) is acentuated : 0

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted (edited)

Aumentar a memória usada para guardar os dados lidos do buffer de leitura é declarar uma variável tipo 'frasein [200]' em vez de 'frasin [100]' no meu código??

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Posted

Aumentar a memória usada para guardar os dados lidos do buffer de leitura é declarar uma variável tipo 'frasein [200]' em vez de 'frasin [100]' no meu código??

a razão está no limite de caracteres dados na função fgets:

#define BUFFER_SIZE 256

// ...

int main()
{
   char readed[bUFFER_SIZE] = {0};

   // ...

   fgets(readed, BUFFER_SIZE, stdin);

   // ...
}

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.