Boas! Comecei recentemente a estudar C++ mas estou com dificuldades em concluir um programa,gostaria de pedir ajuda aos membros do forum para a sua conclusão. O código: #include<iostream> using namespace std; int main(void){ int age ; cout << "Enter your age\n"; cout << "Incert the letter e to exit\n"; do { cin >> age; if(age >= 18 ){ cout << "You are an adult\n"; } else {cout << "You are a kid\n";} } while(age != 'e'); return 0; } A intenção: Se introduzirmos a idade de uma pessoa dizer se ela é um adulto ou uma criança, e caso se seleccione a letra 'e' ele se fecha. IDE: DEV-C++ Que estou fazendo de errado?? Agradecia qualquer ajuda.
Em vez de idade ser um int faz string e depois no if fazes um atoi (se não conheceres vê no cppreference). O que está aí a dar asneira é leres supostamente um inteiro e depois escreves a letra..
Obrigado pela ajuda a parte do char percebi mas a do atoi nao poderia exemplificar e comentar por favor??
A ideia é mudar o tipo da variável age para string em vez de inteiro. Assim a stream cin guarda o valor em age quer seja inteiro, quer seja a letra e. Na cláusula if, dentro do while, ao fazer a comparação, usa-se a função atoi para converter string em inteiro e assim já faz sentido comparar com um valor numérico. A função atoi devolve um inteiro e recebe como único argumento um pointer para char, neste caso, a string age. O código seguinte irá funcionar. A classe string no C++ tem um método que retorna o pointer para o seu primeiro caracter - é isso que é usado como argumento para o atoi. Código: #include <iostream> #include <cstdlib> using namespace std; int main(){ string age; int idade; cout << "Enter your age\n"; cout << "Incert the letter e to exit\n"; do { cin >> age; idade = atoi(age.c_str()); if(idade >= 18 ) { cout << "You are an adult\n"; } else { cout << "You are a kid\n"; } } while(age != "e"); return 0; } Esta abordagem traz vários problemas. Experimenta colocar algo que não um inteiro ou a letra "e" no input para ver o que acontece. Tal como na reference do atoi, se o argumento que entrada não puder ser convertido o comportamento da resposta é indefinido. Uma outra forma mais típica sem recurso a directivas do C será o stoi, mas esta faz uso da função que exemplifico a seguir. Um código mais funcional fará uso da função strtol que tem o mesmo objectivo que o atoi. Esta permite muito mais flexibilidade da detecção de erros. Se quiseres posso explicar como funciona mas como não foi pedido apenas deixo aqui o código. Código: #include <iostream> #include <cstdlib> using namespace std; int main(){ string age; int idade; char * carac; cout << "Enter your age\n"; cout << "Incert the letter e to exit\n"; do { cin >> age; idade = strtol(age.c_str(), &carac, 10); if(idade <= 0 || *carac != '\0'){ cout << "Invalid age entered\n"; } else { if(idade <= 18 ) { cout << "You are a kid\n"; } else { cout << "You are an adult\n"; } } } while(age != "e"); return 0; } Caso a linguagem tenha sido muito técnica e precisas de esclarecimento adicional, pergunta!
Obrigado o código era exactamente o que pretendia mas reparo que quando introduzo o "e" aparece rapidamente Invalid age entered e depois se fecha rapidamente por que isto acontece??. Agradecia que me explica-se como funciona o strtol, e o facto de no while o e estar com "" e não ''.
Ao colocar "e" repare que a condição do while deixa de ser satisfeita. De facto agora age = "e" e por isso não ocorre mais nenhum ciclo. É executada a próxima instrução que é o return do main e por isso o programa fecha-se. Para evitar isso simplesmente podes-se substituir o while actual por while(1). Assim o ciclo está sempre a ser executado indefinidamente. No while estão as aspas em vez das plicas porque age é uma string e não um char. O strtol é semelhante ao atoi só que devolve o inteiro 0 caso haja problemas na conversão. Os argumentos que requer são a própria string ou, como é uma função que vem do C, o ponteiro para array de chars. O segundo argumento é um ponteiro para um char de forma a lá colocar, em caso de erro, qual foi o último caractere a ser convertido. Caso o último caractere a ser convertido seja '\0' isto significa que não houve problema nenhum já que '\0' delimita o final de uma string - isto significa que conseguiu converter tudo até ao último caractere. O último argumento que recebe é um inteiro, que eu pus 10 pois representa base com que trabalhamos e nós trabalhamos com a base decimal. Caso não queiramos verificar qual o caractere último a ser convertido e ficamos bem com um 0 caso haja problemas na conversão, posso especificar o segundo argumento como NULL. Como queria fazer o código o mais robusto possível e porque 0 é uma idade válida se arredondada, isto significaria que mesmo que puséssemos 0 na consola ele ia converter para 0 na mesma só que daria um erro pois a verificação não sabe distinguir entre o retorno nulo devido a erro ou um retorno nulo legítimo, isto é, a string ter sido de facto "0"... então coloquei uma outra verificação naquele if. Disse que para além de dar erro para idades negativas dá erro caso o último caractere a ser lido não seja um '\0' porque se for quer dizer que o strtol leu e converteu tudo até ao fim e aquilo é de facto um zero, caso contrário, não, significando assim que o foi inserido na consola não foi um inteiro.