calculadora

1. calculadora

felipe
phellipe_

(usa Slackware)

Enviado em 05/12/2018 - 15:57h

olá...
estou com esse codigo, mas não consigo fazer funcionar!
qualquer digito que faço eu saio do programa:

#include <stdio.h>
#include <stdlib.h>
//variaveis globais
int strop, str0, str1, a, b;;
char op[10], n0[1000], n1[1000];
float t;

float mais(){
str0 = strlen(n0);
str1 = strlen(n1);
for(a = 0; a <= str0; a++){
for(b = 0; b <= str1; b++){
t = a + b;
printf("Result: %.2f\n", t);
break;
}
}


}
float menos(){
str0 = strlen(n0);
str1 = strlen(n1);
for(a = 0; a <= str0; a++){
for(b = 0; b <= str1; b++){
t = a - b;
printf("Result: %.2f\n", t);
break;
}
}


}
float vezes(){
str0 = strlen(n0);
str1 = strlen(n1);
for(a = 0; a <= str0; a++){
for(b = 0; b <= str1; b++){
t = a * b;
printf("Result: %.2f\n", t);
break;
}
}


}
float divide(){
str0 = strlen(n0);
str1 = strlen(n1);
for(a = 0; a <= str0; a++){
for(b = 0; b <= str1; b++){
t = a / b;
printf("Result: %.2f\n", t);
break;
}
}


}
int main(){
printf("||=======================================================||\n");
printf("||=== xcal v3.0 by: phellipe_ ===||\n");
printf("||=======================================================||\n");
printf("|| Escolha uma opção ||\n");
printf("|| (1) + (2) - (3) x (4) ÷ (0) Sair ||\n");
printf("||=======================================================||\n");
printf("Operação: ");
scanf("%[^\n]s%*c", &op);
strop = strlen(op);
if(strop == 1){
if(op > 47 && op < 58){
if(op == 1){
mais();
}
else if(op == 2){
menos();
}
else if(op == 3){
vezes();
}
else if(op == 4){
divide();
}
else if(op == 0){
printf("Saindo... OK!");
exit(0);
}
else{
printf("Digite uma opção válida!\n");
}
}
}

return 0;
}



  


2. Re: calculadora

-
BiaMonteiro

(usa Arch Linux)

Enviado em 05/12/2018 - 16:45h

O erro ocorre pois quando você usou o scanf, trabalhou com caracteres. E no C/C++, os caracteres possuem uma numeração que os identifica, por exemplo o número 65 representa a letra 'a'. Quando no if foi utilizado o operador "==" ao lado de 1, 2, 3 e 4, você está dizendo ao programa o seguinte: se a variável tal for igual ao caractere de número 0 (que não é numérico nem alfabético), faça isso, senão, se essa mesma variável for igual ao caractere de número 1 (também não é) e assim por diante.

A solução é você fazer isto nos if's: (... == '0'), (... == '1'), (... == '2') ... (... == '4').

E uma sugestão:

-> Tente usar o switch nesse código ao invés do if. É uma melhor prática de programação.


3. Re: calculadora

felipe
phellipe_

(usa Slackware)

Enviado em 05/12/2018 - 16:46h

atualizei, mas agora entra no else:

#include <stdio.h>
#include <stdlib.h>
//variaveis globais
int strop, str0, str1, a, b;;
char op[10], n0[1000], n1[1000];
float t;

float mais(){
str0 = strlen(n0);
str1 = strlen(n1);
for(a = 0; a <= str0; a++){
for(b = 0; b <= str1; b++){
t = a + b - 1;
}
}


}
float menos(){
str0 = strlen(n0);
str1 = strlen(n1);
for(a = 0; a <= str0; a++){
for(b = 0; b <= str1; b++){
t = a - b - 1;
}
}


}
float vezes(){
str0 = strlen(n0);
str1 = strlen(n1);
for(a = 0; a <= str0; a++){
for(b = 0; b <= str1; b++){
t = a * b - 1;
}
}


}
float divide(){
str0 = strlen(n0);
str1 = strlen(n1);
for(a = 0; a <= str0; a++){
for(b = 0; b <= str1; b++){
t = a / b - 1;
}
}


}
int main(){
printf("||=======================================================||\n");
printf("||=== xcal v3.0 by: phellipe_ ===||\n");
printf("||=======================================================||\n");
printf("|| Escolha uma opção ||\n");
printf("|| (1) + (2) - (3) x (4) ÷ (0) Sair ||\n");
printf("||=======================================================||\n");
printf("Operação: ");
scanf("%[^\n]s%*c", &op);
strop = strlen(op);
if(strop == 1){
if(op > 47 && op < 58){
if(op == 1){
mais();
}
else if(op == 2){
menos();
}
else if(op == 3){
vezes();
}
else if(op == 4){
divide();
}
else if(op == 0){
printf("Saindo... OK!");
exit(0);
}
else{
printf("Digite uma opção válida!\n");
}
}
else{
printf("Digite uma opção válida!\n");
}
}
else{
printf("Digite uma opção válida!\n");
}

return 0;
}



4. Re: calculadora

-
BiaMonteiro

(usa Arch Linux)

Enviado em 05/12/2018 - 16:50h

phellipe_ escreveu:

atualizei, mas agora entra no else:

#include <stdio.h>
#include <stdlib.h>
//variaveis globais
int strop, str0, str1, a, b;;
char op[10], n0[1000], n1[1000];
float t;

float mais(){
str0 = strlen(n0);
str1 = strlen(n1);
for(a = 0; a <= str0; a++){
for(b = 0; b <= str1; b++){
t = a + b - 1;
}
}


}
float menos(){
str0 = strlen(n0);
str1 = strlen(n1);
for(a = 0; a <= str0; a++){
for(b = 0; b <= str1; b++){
t = a - b - 1;
}
}


}
float vezes(){
str0 = strlen(n0);
str1 = strlen(n1);
for(a = 0; a <= str0; a++){
for(b = 0; b <= str1; b++){
t = a * b - 1;
}
}


}
float divide(){
str0 = strlen(n0);
str1 = strlen(n1);
for(a = 0; a <= str0; a++){
for(b = 0; b <= str1; b++){
t = a / b - 1;
}
}


}
int main(){
printf("||=======================================================||\n");
printf("||=== xcal v3.0 by: phellipe_ ===||\n");
printf("||=======================================================||\n");
printf("|| Escolha uma opção ||\n");
printf("|| (1) + (2) - (3) x (4) ÷ (0) Sair ||\n");
printf("||=======================================================||\n");
printf("Operação: ");
scanf("%[^\n]s%*c", &op);
strop = strlen(op);
if(strop == 1){
if(op > 47 && op < 58){
if(op == 1){
mais();
}
else if(op == 2){
menos();
}
else if(op == 3){
vezes();
}
else if(op == 4){
divide();
}
else if(op == 0){
printf("Saindo... OK!");
exit(0);
}
else{
printf("Digite uma opção válida!\n");
}
}
else{
printf("Digite uma opção válida!\n");
}
}
else{
printf("Digite uma opção válida!\n");
}

return 0;
}

É para você fazer isto:
if(op == '1'){
mais();
}
else if(op == '2'){
menos();
}
else if(op == '3'){
vezes();
}
else if(op == '4'){
divide();
}
else if(op == '0'){
printf("Saindo... OK!");
exit(0);
}


5. Re: calculadora

felipe
phellipe_

(usa Slackware)

Enviado em 05/12/2018 - 16:51h

BiaMonteiro escreveu:

O erro ocorre pois quando você usou o scanf, trabalhou com caracteres. E no C/C++, os caracteres possuem uma numeração que os identifica, por exemplo o número 65 representa a letra 'a'. Quando no if foi utilizado o operador "==" ao lado de 1, 2, 3 e 4, você está dizendo ao programa o seguinte: se a variável tal for igual ao caractere de número 0 (que não é numérico nem alfabético), faça isso, senão, se essa mesma variável for igual ao caractere de número 1 (também não é) e assim por diante.

A solução é você fazer isto nos if's: (... == '0'), (... == '1'), (... == '2') ... (... == '4').

E duas sugestões:

-> Tente usar o switch ao invés do if. É uma melhor prática de programação.
-> Ao invés de else if no final, use else. Se eu digitar 700, por exemplo, ele irá sair do programa.

obrigado pela ajuda, mas continua a mesma coisa, vou tentar com switch case como vc disse!
obrigado por me ajudar!




6. Re: calculadora

-
BiaMonteiro

(usa Arch Linux)

Enviado em 05/12/2018 - 16:53h

phellipe_ escreveu:

BiaMonteiro escreveu:

O erro ocorre pois quando você usou o scanf, trabalhou com caracteres. E no C/C++, os caracteres possuem uma numeração que os identifica, por exemplo o número 65 representa a letra 'a'. Quando no if foi utilizado o operador "==" ao lado de 1, 2, 3 e 4, você está dizendo ao programa o seguinte: se a variável tal for igual ao caractere de número 0 (que não é numérico nem alfabético), faça isso, senão, se essa mesma variável for igual ao caractere de número 1 (também não é) e assim por diante.

A solução é você fazer isto nos if's: (... == '0'), (... == '1'), (... == '2') ... (... == '4').

E duas sugestões:

-> Tente usar o switch ao invés do if. É uma melhor prática de programação.
-> Ao invés de else if no final, use else. Se eu digitar 700, por exemplo, ele irá sair do programa.

obrigado pela ajuda, mas continua a mesma coisa, vou tentar com switch case como vc disse!
obrigado por me ajudar!


Na verdade, o switch produzirá o mesmo efeito do if. O código só ficará mais elegante e de fácil manutenção e entendimento.



7. Re: calculadora

-
BiaMonteiro

(usa Arch Linux)

Enviado em 05/12/2018 - 16:56h

Como estou meio ocupada, pode ser que eu esteja explicando mal por não estar vendo muitos detalhes.
Bem, a princípio é para você fazer isto:

if(op == '1'){
mais();
}
else if(op == '2'){
menos();
}
else if(op == '3'){
vezes();
}
else if(op == '4'){
divide();
}
else if(op == '0'){
printf("Saindo... OK!");
exit(0);
}

-> Se não funcionar, tente trocar aspas simples por duplas.
-> Ou substitua por 48 (número 0) a 52 (número 4).


8. Re: calculadora

-
BiaMonteiro

(usa Arch Linux)

Enviado em 05/12/2018 - 16:57h

if(op > 47 && op < 58){

E aqui ponha 53 no lugar de 58.


9. Re: calculadora

Paulo
paulo1205

(usa Ubuntu)

Enviado em 10/12/2018 - 14:56h

phellipe_ escreveu:

olá...
estou com esse codigo, mas não consigo fazer funcionar!


Você cometeu diversos erros comuns em iniciantes.

Uma coisa que eu sempre recomendo, porque ajuda a diagnosticar a grande maioria de erros desse tipo, é ligar o máximo possível de opções de diagnóstico e alerta do compilador. No caso do GCC, quer usado diretamente, quer quando invocado pelo ambiente gráfico de desenvolvimento, eu recomendo as seguintes opções de diagnóstico:
-std=c11 -Wall -Werror -pedantic-errors -O2 

Legenda: -std=c11 pede que se utilize a versão de 2011 do padrão (standard, de onde vem “-std”) do C; -Wall faz com que o compilador mostre todas (“all”) as mensagens de alerta (warning, de onde vem “-W”); -Werror transforma todas as mensagens de alerta em erros, impedindo a compilação de prosseguir (para que você seja forçado a corrigir o problema apontado, em vez de preguiçosamente deixar o aviso passar e “torcer para funcionar assim mesmo”); -pedantic-errors faz com que o compilador seja pedantemente intransigente com relação a código perigoso, e trata todas as violações como erros que impedem a compilação de prosseguir; e -O2 liga o segundo nível de otimização de código, que, embora não tenha propósito original de servir para diagnóstico, ajuda a identificar alguns casos de código inacessível e variáveis que ficam sem uso.

Ao compilar seu programa original (que eu chamei de calc.c) apenas com o comando “gcc calc.c”, ele gerou 13 alertas, mas produziu um código executável. Usando as opções de diagnóstico que eu sugeri acima, foram 19 mensagens de erro (não mais apenas alerta), com descrições precisas de causa, incluindo erros ao usar scanf():
calc.c:4:31: error: ISO C does not allow extra ‘;’ outside of a function [-Wpedantic]
int strop, str0, str1, a, b;;
^
calc.c: In function ‘mais’:
calc.c:9:12: error: implicit declaration of function ‘strlen’ [-Wimplicit-function-declaration]
str0 = strlen(n0);
^~~~~~
calc.c:9:12: error: incompatible implicit declaration of built-in function ‘strlen’ [-Werror]
calc.c:9:12: note: include ‘<string.h>’ or provide a declaration of ‘strlen’
calc.c: In function ‘menos’:
calc.c:22:12: error: incompatible implicit declaration of built-in function ‘strlen’ [-Werror]
str0 = strlen(n0);
^~~~~~
calc.c:22:12: note: include ‘<string.h>’ or provide a declaration of ‘strlen’
calc.c: In function ‘vezes’:
calc.c:35:12: error: incompatible implicit declaration of built-in function ‘strlen’ [-Werror]
str0 = strlen(n0);
^~~~~~
calc.c:35:12: note: include ‘<string.h>’ or provide a declaration of ‘strlen’
calc.c: In function ‘divide’:
calc.c:48:12: error: incompatible implicit declaration of built-in function ‘strlen’ [-Werror]
str0 = strlen(n0);
^~~~~~
calc.c:48:12: note: include ‘<string.h>’ or provide a declaration of ‘strlen’
calc.c: In function ‘main’:
calc.c:68:15: error: format ‘%[^
’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[10]’ [-Werror=format=]
scanf("%[^\n]s%*c", &op);
~~~^~ ~~~
calc.c:69:13: error: incompatible implicit declaration of built-in function ‘strlen’ [-Werror]
strop = strlen(op);
^~~~~~
calc.c:69:13: note: include ‘<string.h>’ or provide a declaration of ‘strlen’
calc.c:71:13: error: comparison between pointer and integer
if(op > 47 && op < 58){
^
calc.c:71:24: error: comparison between pointer and integer
if(op > 47 && op < 58){
^
calc.c:72:14: error: comparison between pointer and integer
if(op == 1){
^~
calc.c:75:19: error: comparison between pointer and integer
else if(op == 2){
^~
calc.c:78:19: error: comparison between pointer and integer
else if(op == 3){
^~
calc.c:81:19: error: comparison between pointer and integer
else if(op == 4){
^~
calc.c: In function ‘mais’:
calc.c:20:3: error: control reaches end of non-void function [-Werror=return-type]
}
^
calc.c: In function ‘menos’:
calc.c:33:3: error: control reaches end of non-void function [-Werror=return-type]
}
^
calc.c: In function ‘vezes’:
calc.c:46:3: error: control reaches end of non-void function [-Werror=return-type]
}
^
calc.c: In function ‘divide’:
calc.c:59:3: error: control reaches end of non-void function [-Werror=return-type]
}
^
calc.c: In function ‘main’:
calc.c:68:5: error: ignoring return value of ‘scanf’, declared with attribute warn_unused_result [-Werror=unused-result]
scanf("%[^\n]s%*c", &op);
^~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors


qualquer digito que faço eu saio do programa:
#include <stdio.h>
#include <stdlib.h>


Você não incluiu <string.h>, para poder trabalhar com funções que manipulam strings.

  //variaveis globais 


Variáveis globais são um dos tipos de coisas que se deve usar com moderação. Contudo, você fez globais todos os dados do programa, incluindo varáveis usadas como contadores em laços de repetição.

Não chega a ser errado, mas não definitivamente é usual. Seria melhor evitar.

  int strop, str0, str1, a, b;;
char op[10], n0[1000], n1[1000];
float t;

float mais(){
str0 = strlen(n0);
str1 = strlen(n1);


A função strlen() mede o comprimento de uma string. É isso mesmo que você quer?

    for(a = 0; a <= str0; a++){
for(b = 0; b <= str1; b++){
t = a + b;
printf("Result: %.2f\n", t);
break;


Por que esse break? Na prática, ele mata o laço de repetição interno logo após a primeira iteração, pois transforma o for mais interno em algo equivalente ao seguinte if.
if((b=0)<=str1){ // Essa condição será sempre verdadeira, porque str1 será sempre maior ou igual a zero
t=a+b; // Ou “t=a;”, dado que b será sempre zero.
printf("Result: %.2f\n", t);
}


      }
}


Não entendi o propósito desses laços de repetição. Você pega os comprimentos de cada string e depois cria dois laços de repetição que percorrem o caminho de zero até cada um dos comprimentos, somando os valores intermediários das variáveis de controle de cada laço de repetição (não dos dados que elas indexariam), e ainda por cima com a particularidade de que o laço de repetição mais interno é prematuramente interrompido.

    

}


Você disse que a função retorna um valor do tipo float, mas cadê o comando de retorno desse valor?

Esse problema e os já apresentados acima se repetem nas outras funções. Por isso, não vou apontá-los especificamente de novo.

  float menos(){
str0 = strlen(n0);
str1 = strlen(n1);
for(a = 0; a <= str0; a++){
for(b = 0; b <= str1; b++){
t = a - b;
printf("Result: %.2f\n", t);
break;
}
}


}
float vezes(){
str0 = strlen(n0);
str1 = strlen(n1);
for(a = 0; a <= str0; a++){
for(b = 0; b <= str1; b++){
t = a * b;
printf("Result: %.2f\n", t);
break;
}
}


}
float divide(){
str0 = strlen(n0);
str1 = strlen(n1);
for(a = 0; a <= str0; a++){
for(b = 0; b <= str1; b++){
t = a / b;
printf("Result: %.2f\n", t);
break;
}
}


}
int main(){
printf("||=======================================================||\n");
printf("||=== xcal v3.0 by: phellipe_ ===||\n");
printf("||=======================================================||\n");
printf("|| Escolha uma opção ||\n");
printf("|| (1) + (2) - (3) x (4) ÷ (0) Sair ||\n");
printf("||=======================================================||\n");
printf("Operação: ");
scanf("%[^\n]s%*c", &op);


Você tentou usar scanf() de uma maneira engenhosa. Contudo, scanf() é uma função bastante complexa (eu reputo como a função mais complexa de toda a biblioteca de funções padronizadas do C), e você acabou se atrapalhando de diversas maneiras. Eis alguns dos equívocos:

  • "%[" é uma conversão de seu próprio direito, e utiliza um argumento pós-fixado terminado com o caráter “]” (no seu caso, tal argumento pós-fixado é “^\n”). Não se trata de um modificador da conversão "%s", de modo que aquele caráter s que vem depois do fechamento de colchetes não tem o sentido que provavelmente você imaginou. (Esse é um erro muito comum em apostilas e por parte de professores que não sabem C tão bem assim. Portanto, muito cuidado com o material que você recebe!)

  • O caráter 's' presente na string de formatação é interpretado como algo a ser buscado literalmente na string digitada pelo usuário do programa. Se esse 's' não for encontrado na string, a função scanf() vai interromper o processamento antes de chegar ao final da string de formatação.

  • Entretanto, o 's' nunca será encontrado, porque a conversão que vem imediatamente antes dele não será interrompida até que apareça um '\n' (ou que ocorra um erro de leitura). Ao aparecer um '\n' na entrada, a conversão "%[" termina, deixando o '\n' no buffer de entrada para ser comparado com o que vem a seguir. Mas como o que vem a seguir na string de formatação é um 's', esse '\n' não vai lhe corresponder, sendo deixado ainda no buffer de entrada e provocando a interrupção prematura do processamento de scanf().

  • Por conta da interrupção prematura, também o "%*c" nunca será atingido e, portanto, não provocará o consumo de nenhum caráter do buffer de entrada.

  • Existe um erro de correspondência de tipos entre a conversão "%[" e o argumento &op: a primeira espera um ponteiro para caracteres, e o tipo da segunda é “ponteiro para arrays com 10 elementos do tipo caráter”. Você deveria ter usado como argumento apenas “op” (sem o operador &), de modo que o o array de caracteres seja automaticamente convertido em ponteiro para caracteres.

  • Há um risco de segurança, pois você está solicitando a leitura de uma quantidade ilimitada de caracteres para um destino que tem comprimento de apenas 10 bytes. Seria melhor que você limitasse a quantidade máxima de caracteres que podem ser recebidos.

  • Ainda pelo ponto de vista de segurança do código, você não testa sequer se a leitura foi bem sucedida antes de prosseguir executando código que depende do que deve ter sido lido. O resultado disso é totalmente indefinido.

Assim sendo, seria bom que você mudasse a forma de fazer sua leitura.

A primeira coisa a fazer seria uma leitura cuidadosa do comportamento da função scanf() (que, como eu disse, é bastante complexa), até para entender os pontos em que errou e como você os deve corrigir. Contudo, se você é iniciante, é possível que a documentação toque em pontos que você ainda não domina. Se for o caso, pesquise, ou volte aqui expondo sua dúvida.

Depois disso, não apenas você deve corrigir a string de formatação, mas também testar o valor de retorno de scanf(), para ver se ela realmente leu alguma coisa. (Eu adicionalmente mudaria também os tipos dos seus dados. Não consegui entender por que motivo você está usando strings com sua calculadora, em lugar de dados numéricos.)

    strop = strlen(op);
if(strop == 1){
if(op > 47 && op < 58){


Seria melhor usar algo como “if(isdigit(op))”.

      	if(op == 1){
mais();
}
else if(op == 2){
menos();
}
else if(op == 3){
vezes();
}
else if(op == 4){
divide();
}
else if(op == 0){
printf("Saindo... OK!");
exit(0);
}
else{
printf("Digite uma opção válida!\n");
}
}
}

return 0;
}









Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts