Loki Posted February 23, 2014 at 03:03 PM Report #546359 Posted February 23, 2014 at 03:03 PM (edited) Boas mais uma vez, preciso novamente da vossa ajuda. É o seguinte com esta função retorna-me a posição correspondente á letra que eu escolher, ou seja se for um A ela retorna-me um 0. O problema é quando tento chamar esta mesma função dentro de outra para permitir que um utilizador introduza um CHAR e que esse se transforme num INT (ou seja a posição do char introduzido). não sei se me fiz compreender. #include <stdio.h> #include <stdlib.h> char letras[27] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','\0'}; int Caracteres(char); int main(void) { char linha; int i=0, f; printf("Linha: "); scanf("%c",&linha); f=Caracteres(linha); printf("Linha: %d",f); return 0; } int Caracteres(char l){ int i; for (i = 0; i < 27; i++) { if (letras[i] == l) { return i; } } } Esta é a função onde eu chamo a anterior, não coloquei aqui a função inteira porque só a chamo aqui nesta zona. O problema é que esta função desde que mudei para caracter nem sequer me pede para colocar a Linha, passa-se e crasha mas se for com inteiros funciona perfeitamente. //Submarino if(sub<4){ printf("\n\nColoque os Submarino\n"); printf("Digite as coordenadas(EX:Linha: 0 / Coluna:0)\n"); printf("Linha: "); //Pede a letra scanf("%c",&linha); // Guarda a letra f=Caracteres(linha);// Aqui chamo a função para ela guardar em f a posição da letra l=f-1; // Aqui tiro 1 porque os arrays começam no 0 e o utilizador coloque sempre uma posição acima } não sei se fui explicito o suficiente. Agradeço alguma ajuda, o thoga31 já me safou ontem e esta comunidade tem-me valido. Obrigado a Todos. Edited February 23, 2014 at 03:05 PM by thoga31 GeSHi
thoga31 Posted February 23, 2014 at 03:15 PM Report #546360 Posted February 23, 2014 at 03:15 PM (edited) scanf de caracteres e strings... um clássico de iniciação ao C 😛 Para leres um caracter, tens duas formas: scanf(" %c", &foo); // nota o espaço antes de "%c" - indica que deve ignorar certos caracteres, como o Enter de quando indicas a entrada de dados foo = getchar(); // obtém um caracter e não necessita de Enter, mais usado para chars Outra coisa, falta-te o 'Z'. Por fim, essa forma de resolver o problema, é preciso ser mesmo assim ou não te lembras de outra forma? Edited February 23, 2014 at 03:15 PM by thoga31 Knowledge is free!
Guest Posted February 23, 2014 at 03:32 PM Report #546366 Posted February 23, 2014 at 03:32 PM em array de char não tens qualquer tipo de necesidade de usar o \0. Este só é utilizado para denotar o final de uma string. A criação de uma função também esta no formulario? se não é apenas mais recursos que vais gastar. por isso tira o \0 mete o tal Z. e faz uma solução mais generica usando o sizeof para saberes o tamanho, de seguida um ciclo com a comparação(o if). e no fim devolves o i. Outra coisa estas a usar também a stdlib mas não estas a usar nenhuma função lá definida, utiliza apenas a stdio 😉
Loki Posted February 23, 2014 at 03:38 PM Author Report #546369 Posted February 23, 2014 at 03:38 PM Bem mais uma vez obrigado, tens sido a minha salvação, isto é para o jogo da Batalha Naval, que é para entregar amanhã 🙂 mas já está feito agora ando a limar todos os pontos fracos. E este problema com Chars já me assolava á bastante tempo 😄 . Esta foi a forma que encontrei para resolver este problema, não me veio á ideia outra visto que tinha problemas com os Char's lol resolvi fazer uma matriz de inteiros e mascara-la depois na apresentação com Char... Aproveito só para perguntar eu trabalho em linux com o Eclipse segundo sei o eclipse não gera executaveis, pois não? Qual o programa que eu poderia usar para gerar o meu executável. Mais uma vez Obrigado. Obrigado pelos concelhos Mkman vou imediatamente retificar, recursos é o que não preciso gastar quanto menos melhor.
Guest Posted February 23, 2014 at 03:44 PM Report #546371 Posted February 23, 2014 at 03:44 PM Loki se já resolveste, fica aqui uma proposta de resolução http://ideone.com/TkwWxP
Loki Posted February 23, 2014 at 04:20 PM Author Report #546378 Posted February 23, 2014 at 04:20 PM Assim derrepente deparei-me com um problema, e se o utilizador colocar uma letra minuscula? Já não vai funcionar, existe alguma maneira de comparar para ver se é maiuscula ou minuscula? E quanto ao compilador, para gerar um executável sabes-me dizer algum, para linux. Obrigado pela solução que me indicas-te é parecida com a minha, não entendi a utilização do sizeof, o length vai guardar o tamanho em bytes que o array ocupa em memória certo, era com o objectivo de se tornara dinâmico e não dependente do numero de char do array?
thoga31 Posted February 23, 2014 at 04:40 PM Report #546381 Posted February 23, 2014 at 04:40 PM (edited) Hoje vou dar uma solução. Não usei arrays, e tenho em conta as minúsculas. Vê se percebes 😉 #include <stdio.h> #include <ctype.h> int main(void) { char foo; foo = toupper(getchar()); printf("%d", foo - 'A'); return 0; } Edit: ou então outra mais "kamikaze" #include <stdio.h> #include <ctype.h> #include <string.h> int main(void) { char alpha[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char c = toupper(getchar()); char *pos = strchr(alpha, c); printf("%d", pos == NULL ? -1 : pos - alpha + 1); return 0; } Edit2: corrigi o 2º código para lidar com inputs que não sejam letras. Edited February 23, 2014 at 08:25 PM by thoga31 Knowledge is free!
Guest Posted February 23, 2014 at 05:09 PM Report #546382 Posted February 23, 2014 at 05:09 PM @thoga31 se ele já estava a ter dificuldade assim comeste lhe o caco. Loki o codigo do thoga tem a ver com a tabela ASCII e faz operações para saber a posição. Como já deves ter percebido chars são representados por numeros inteiros. Se tens alguma distribuição de linux instalada o gcc já deve vir instalado por default. Tens ainda o clang. http://pt.wikipedia.org/wiki/ASCII
thoga31 Posted February 23, 2014 at 05:15 PM Report #546384 Posted February 23, 2014 at 05:15 PM @thoga31 se ele já estava a ter dificuldade assim comeste lhe o caco. Eu sei que dei uma solução mais complexa para o @Loki. No entanto, é interessante ver que há formas de brincar com as características dos chars e das strings. O @Loki pode não perceber agora à primeira vista, mas fica alerta para a existência de tais possibilidades. Mais, se o @Loki quiser, eu explico com quantas palavras forem necessárias o meu código. Assim talvez até cimente certos conhecimentos que ainda estão meios no ar tipo poeira. Pelo menos foi assim que eu aprendi muita coisa ao longo dos últimos anos: vendo coisas que não compreendia. Incentivava-me a querer saber mais. 🙂 Knowledge is free!
HappyHippyHippo Posted February 23, 2014 at 08:15 PM Report #546400 Posted February 23, 2014 at 08:15 PM @thoga31 : falta a validação dos dados de entrada ... IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
thoga31 Posted February 23, 2014 at 08:19 PM Report #546402 Posted February 23, 2014 at 08:19 PM (edited) @thoga31 : falta a validação dos dados de entrada ... O meu objectivo não era fazer um programa completo e totalmente seguro etc etc, tenho plena noção que falta a validação do input. Sim, também podia mostrar como isso se faz, mas não considerei prioritário neste tópico. O essencial são os algoritmos/fórmulas utilizados, e eles estão lá. Portanto, quanto aos algoritmos, enganei-me? É que eu escrevi o código mas nem testei 😛 Edited February 23, 2014 at 08:19 PM by thoga31 Knowledge is free!
HappyHippyHippo Posted February 23, 2014 at 08:24 PM Report #546404 Posted February 23, 2014 at 08:24 PM não parece que esteja mal, só não existe a necessidade do cast explícito no primeiro código. no entanto, ao ler a tua primeira resposta (segunda entrada do tópico) fiquei com a ideia que o problema era leitura de dados do teclado. IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Loki Posted February 23, 2014 at 11:27 PM Author Report #546423 Posted February 23, 2014 at 11:27 PM Bem nem sei por onde começar, em primeiro por agradecer a todos, 2º realmente se possivel thoga31 explica-me que fiquei a nora... Por ultimo o HappyHippyHippo tem razão isto relaciona-se com o input de dados do teclado. Mais uma vez vos agradeço, e beber do vosso conhecimento é só brutal... PS: A segunda do thoga31 então matou-me...
Flinger Posted February 24, 2014 at 10:27 AM Report #546436 Posted February 24, 2014 at 10:27 AM printf("%d", pos == NULL ? -1 : pos - alpha + 1); AHAH, vocês metem isto à frente de um iniciado, só posso mesmo imaginar a cara dele a olhar para isto... Faz-me voltar ao meu tempo de Secundário, se visse isto à frente achava que quem o fez devia ser meio avariado 😛 Não é que seja difícil, mas para que nunca viu... Explicando isto um pouco, é basicamente um if. a expressão completa (pos == NULL ? -1 : pos - alpha + 1) equivale a '-1' se 'pos==NULL', senão equivale a 'pos - alpha + 1' Depois tens o uso da função strchr: http://linux.die.net/man/3/strchr Involve apontadores, algo que eu não tenho a certeza de já teres abordado. Basicamente procura-te um caracter dentro da string. 1 Report
thoga31 Posted February 24, 2014 at 03:37 PM Report #546485 Posted February 24, 2014 at 03:37 PM (edited) 2º realmente se possivel thoga31 explica-me que fiquei a nora... PS: A segunda do thoga31 então matou-me... Uma coisa que te aconselho a veres é apontadores. Digo isto não com base neste tópico mas essencialmente com base no outro. C não vive sem eles, e são parte essencial da programação nesta linguagem. Passando então a explicar os meus códigos: #include <stdio.h> #include <ctype.h> int main(void) { char foo; foo = toupper(getchar()); printf("%d", foo - 'A'); return 0; } Estou a utilizar o método toupper, da biblioteca ctype, que pega no caracter lido com getchar e o transforma na letra maiúscula correspondente. Em C, um char não é mais do que um número inteiro. Desta forma, podes fazer contas com chars. Cada caracter tem um número que o identifica na Tabela ASCII, e é com base nela que eu trabalhei. Os caracteres alfanuméricos estão todos seguidos, começando no "A" na posição 65 e acabando no "Z" na posição 90. Os caracteres minúsculos estão mais à frente. Vê o link para perceberes 😉 Portanto, para saber que caracter é, o que faço eu? Se eu quero que 'A' seja 0, então 'A'-'A'=0 uma vez que 'A'=65. Se eu quiser a "posição" do 'D', faço 'D'-'A'=3, ou seja, 68-65 uma vez que 'D'=68. Desta forma, eu subtraio o caracter lido ao 'A', que é o nosso caracter de referência. O segundo código é mais kamikaze e já tem validação de dados. #include <stdio.h> #include <ctype.h> #include <string.h> int main(void) { char alpha[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char c = toupper(getchar()); char *pos = strchr(alpha, c); printf("%d", pos == NULL ? -1 : pos - alpha + 1); return 0; } Portanto, eu tenho uma strinh alpha que representa o alfabeto em letras maiúsculas. Mais uma vez, leio um caracter do teclado e transformo-o no seu respectivo caracter maiúsculo. De seguida, usei a função strchr. Esta função pega numa String e num caracter e procura esse caracter na String. O que esta função retorna não é a posição! Ela retorna o endereço de memória em que está o caracter na String! Não sei se já viste que uma String pode ser declarada como char s[] e char *s - um apontador. Estranho, não? Não é. Uma String é um array de chars com uma característica particular: deve ter um caracter de terminação, o '\0'. Existe uma panóplia de métodos na biblioteca string que nos facilita trabalhar com estes "meninos". Desta forma, alpha é um endereço de memória que indica o início de uma String. Uma vez que não defini um tamanho para ela, o compilador trata de o calcular, além de inserir por mim o caracter de terminação '\0' no final (daí eu não o ter escrito). Ora, o caracter 'A' está (hipoteticamente falando) na posição 1234 da memória, o 'B' no 1235 e por aí em diante. Isto é verdade porque um char tem 1 byte. Se tivesse por exemplo 2 bytes a história mudava de figura: o 'B' estaria 2 posições à frente uma vez que o 'A' estava a ocupar 2 bytes. Mas felizmente este não é o caso aqui, mas convém referir. Então, o strchr vai-me devolver o endereço do caracter! Se eu inserir 'C', e se alpha começar no endereço 1234, então vou obter o endereço 1236 como resultado. Como posso fazer cálculos com apontadores, faço pos-alpha que é o mesmo que 1236-1234. Obtenho o resultado pretendido: 2. Neste caso eu decidi somar 1... por força de hábito 😄 Tu queres que o 'A' seja 0, portanto não é para somar 1. Aquela sintaxe "marada"... pos == NULL ? -1 : pos - alpha. Este é o único operador ternário do C. Esta é a sua sintaxe: condicao ? verdade : falso; E é o equivalente de: if (condicao) verdade; else falso; A vantagem de usar este operador neste caso é que evito de ter este pequeno comboio: if (pos == NULL) printf("%d", -1); else printf("%d", pos - alpha); Assim fica mais bonito e prático: printf("%d", pos == NULL ? -1 : pos - alpha); Portanto, imagina que o utilizador não premiu uma letra mas sim um número. O número não está em alpha. O que devolve a função? Devolve NULL, ou seja, um apontador para nada. Ora, se eu obtenho NULL, significa que obtive um input inválido. Neste caso, imprimo um resultado "sem sentido" que indica erro: -1. Não há nenhuma posição negativa, e "-1" é um valor muito tradicional de se usar nestes casos. Pronto, acho que o principal está aqui. Se alguém quiser acrescentar ou corrigir algo, faça as honras da casa. 😄 @Loki, espero que tenhas aprendido coisas novas. 🙂 Cumprimentos. Edited February 24, 2014 at 03:40 PM by thoga31 1 Report Knowledge is free!
HappyHippyHippo Posted February 24, 2014 at 04:08 PM Report #546491 Posted February 24, 2014 at 04:08 PM (edited) Se alguém quiser acrescentar ou corrigir algo, faça as honras da casa. 😄 é possível executar várias operações dentro de um dos ramos do operador ternário (mesmo que não se use as chavetas) usando o separador de instruções ",". a única coisa que se deverá ter em contra é que o valor rvalue da operação será sempre o valor da última instrução: int foo() { return 22; } int bar() { return 23; } int main() { int i = 0, j; j = (i == 0 ? foo(), i = 10 : bar()); printf("j = %d\n", j); // j = 22 return 0; } int foo() { return 22; } int bar() { return 23; } int main() { int i = 0, j; j = (i == 0 ? i = 10, foo() : bar()); printf("j = %d\n", j); // j = 1 return 0; } Edited February 24, 2014 at 04:09 PM by HappyHippyHippo IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now