I've coded this program to get a number and a base as two inputs, then prints the number in the given base, it does work well when the base is less than 10, but when I enter a base like 16, instead of printing the word "A" for 10, or F for 15, the program prints the ASCII value of the words, but I want the words themselves.
#include <iostream>
using namespace std;
int base(int n, int t);
int main()
{
char ch;
do {
int n=0, t=0;
base(n,t);
cout << "\n\nDo you want to continue?(y/n)";
cin >> ch;
} while (ch=='y');
}
int base(int n, int t)
{
cout << "\nPlease enter the number : ";
cin >> n;
cout << "\nPlease enter the base : ";
cin >> t;
int i=80;
int x[i];
int m=n;
for (i=1; n>=t ;i++)
{
int rem;
rem = n%t;
n = n/t;
if (rem>9)
{
switch (char(rem))
{
case 10 :
rem = 'A';
break;
case 11 :
rem = 'B';
break;
case 12 :
rem = 'C';
break;
case 13 :
rem = 'D';
break;
case 14 :
rem = 'E';
break;
case 15 :
rem = 'F';
break;
}
}
x[i]=rem;
}
cout << "The number " << m << " in base " << t << " is = ";
cout << n;
for (int j=(i-1); j>0; j--)
cout << x[j];
return 0;
}
I know it's because I have declared x[i] as an integer, so that's why it's happening, but I don't know how to fix this problem.
To print an ASCII code as a character, you cast it to char. So, instead of
cout << x[j];
You can do
cout << static_cast<char>(x[j]);
However, you currently leave digits below 10 as a number, which after casting to char would be wrong. You could fix that by adding '0' to rem if it's less than 10.
Another possibility is changing the type of x from int to char; that way, you wouldn't have to cast.
Related
Sorry it sounds stupid, but I'm just getting started in C++ programming...
My input checking loop works fine if I want it to accept 'float' numbers, but outputs some weird results if it has to accept only 'int' numbers.
EDIT: Tutorials I read/watched assumed that user wouldn't input things like that, which is dumb...
#include <iostream>
#include <limits>
using namespace std;
// input with check
int num(int i) {
int x=0;
cout<<"Enter #"<<i+1<<": ";
cin>>x;
while(cin.fail()) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
cout<<"Enter INTEGER #"<<i+1<<": ";
cin>>x;
}
return x;
}
int main()
{
int i, min=0, max=0, n=3;
int arr[3];
// save input into array
for(i=0; i<n; i++) { arr[i] = num(i); }
// find 'max' & 'min'
max = arr[0];
for(i=1; i<n; i++) {
if(max < arr[i]) { max = arr[i]; }
}
min = arr[0];
for(i=1; i<n; i++) {
if(min > arr[i]) { min = arr[i]; }
}
cout << endl << "MAX = " << max;
cout << endl << "MIN = " << min;
return 0;
}
For example if I type in 5.2 it takes in the 5, skips one loop and puts out error message on the next loop.
Output:
Enter #1: 2
Enter #2: 5.5
Enter #3: Enter INTEGER #3: g
Enter INTEGER #3: -2
MAX = 5
MIN = -2
EDIT2: I did some digging and I found something that kind of works for my use and is simple enough for my skill level, but still has some quirks. Function just filters out anything that isn't characters you specify between the quotes and checks if '-' is as the first character.
bool isNumeric(string const &str) {
if(str.find_last_of("-")==0 || str.find_last_of("-")==SIZE_MAX) {
return !str.empty() && str.find_first_not_of("-0123456789") == string::npos;
} else { return 0; }
}
int num(int i) {
string str;
cout << "Enter #" << i+1 << ": ";
getline(cin,str);
while(isNumeric(str)==0) {
cout << "Enter INTEGER #" << i+1 << ": ";
getline(cin,str);
}
return stoi(str); // convert string to integer
}
Source: https://www.techiedelight.com/determine-if-a-string-is-numeric-in-cpp/ - method #3
cin read '5'-> integer -> get -> cin read '.' -> not integer -> not get -> n = 5 -> recall func -> cin read '.' -> not integer -> invalid -> cin fail
if you write like this:
int a;
cin >> a;
double b;
cin >> b;
cout << a << " " << b;
with input 5.5, the output will be 5 0.5.
If you want check if your input is integer, you can write like this:
bool isInteger(char* s, int length) {
if (length == 0) return false;
if (s[0] != '-' && s[0] != '+' && !isdigit(s[0])) return false;
for (int i = 1; i < length;) if (!isdigit(s[i++])) return false;
return true;
}
int num(int i) {
char c[11];
cout << "Enter #" << i + 1 << ": ";
cin.getline(c, 11);
while (!isInteger(c, cin.gcount() - 1)) {
cout << "Enter INTEGER #" << i + 1 << ": ";
cin.getline(c, 11);
}
return stoi(c);
}
I am a student in c++, we have started 3 weeks ago. Our assignment is to make a Base Converter without using stoi or atol. We are using a site called Repl.it. I am getting an error called Segmentation Error with doesn't make sense. It started with stringToDecmial. We are referring to the Ascii Table by the way.
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
int strToDecimal(int base, string num);
string decimalToBase(int number, int base);
int main()
{
int menuChoice;
int startBase;
int numberInDecimal;
string number;
cout << "NUMBER BASE CONVERTER 2019" << endl;
cout << "By: Suraj Joshi" << endl << endl;
cout << "Enter number to convert: ";
cin >> number;
cout << "Choose your starting base: " << endl
<< "1. Binary" << endl
<< "2. Octal" << endl
<< "3. Decimal" << endl
<< "4. Hex" << endl;
cin >> menuChoice;
switch (menuChoice)
{
case 1: {
startBase = 2;
break;
}
case 2: {
startBase = 8;
break;
}
case 3: {
startBase = 10;
break;
}
case 4: {
startBase = 16;
break;
}
default: {
startBase = 0;
cout << "Invalid Choice..." << endl;
break;
}
}
numberInDecimal = strToDecimal(startBase, number);
cout << "Binary: " << decimalToBase(numberInDecimal, 2) << endl;
cout << "Decimal: " << numberInDecimal << endl;
cout << "Octal: " << decimalToBase(numberInDecimal, 8) << endl;
cout << "Hex: " << decimalToBase(numberInDecimal, 16) << endl;
return 0;
}
// This is where the problem starts(I Believe) I never experianced the problem
// when this wasnt here
int strToDecimal(int base, string num)
{
int sum = 0;
for (int i = 0; num.length() - 1; ++i) {
if (num[i] > 64)
sum += (num[i] - 55) * pow(base, num.length() - 1 - i);
else
sum += (num[i] - 48) * pow(base, num.length() - 1 - i);
}
return sum;
}
// this can be ingored, This isnt what is causing the problem but feel free to
// look at it, it isnt complete yet
string decimalToBase(int number, int base) {
int rem;
string tempStr(1, number % base + 48);
while (number != 0) {
rem = number % base;
number = number / base;
// str.insert(0, string(1, num % base + 48))
// or string tempStr (1, num % base + 48);
// str.insert(0, tempStr);
switch (rem) {} // switch
} // while
return " ";
}
The segmentation fault is because you're reading past the end of the num string. In your strToDecimal function this line
for (int i = 0; num.length() - 1; ++i) {
does not perform the right termination check. As long as num.length() - 1 contains a non-zero value the loop will continue indefinately. You probably want to change it to:
for (int i = 0; i < num.length(); ++i) {
Below is what I am trying to accomplish. My code works aside from the validation loop. Any help would be greatly appreciated!!
Refactor your code to divide all your tasks into functions. Your variables can be declared in main or as local variables within the functions. Pass in parameters as needed. Do not declare global variables unless it's a constant.
The main program should contain a menu with at least 4 items including "quit" which calls these functions (your tasks) and loops until the user selects quit. An Input validation loop should be included to validate the user's input for their menu selection.
Within the functions, there should be at least one decision structure either an if-then-else based condition or a switch statement.
using namespace std;
void DecimalToBinary(int n) {
int binaryNumber[100], num = n;
int i = 0;
while (n > 0) {
binaryNumber[i] = n % 2;
n = n / 2;
i++;
}
cout << "Binary form of " << num << " is ";
for (int j = i - 1; j >= 0; j--)
cout << binaryNumber[j];
cout << endl;
}
int BinaryToDecimal(int n) {
int decimalNumber = 0;
int base = 1;
int temp = n;
while (temp) {
int lastDigit = temp % 10;
temp = temp / 10;
decimalNumber += lastDigit * base;
base = base * 2;
}
cout << "Decimal form of " << n << " is " << decimalNumber << endl;;
}
int main() {
DecimalToBinary();
BinaryToDecimal(10101);
int choice;
int input;
do {
cout << "Enter 1 to exit the program: \n";
cout << "Enter 2 to enter a binary number: \n";
cout << "Enter 3 to enter a decimal number: \n";
cout << "Enter 4 to do something else: \n";
cin >> input;
switch (input) {
case '1':
choice = 1;
break;
case '2':
choice = 1;
break;
case '3':
choice = 1;
break;
case '4':
choice = 1;
break;
default:
choice = 0;
}
} while (choice);
DecimalToBinary();
BinaryToDecimal(10101);
return 0;
}
int main() {
int choice;
int input;
do {
cout << "Enter 1 to exit the program: \n";
cout << "Enter 2 to enter a binary number: \n";
cout << "Enter 3 to enter a decimal number: \n";
cout << "Enter 4 to do something else: \n";
cin >> input;
switch (input) {
case 1:
choice = 0;
break;
case 2:
int number;
cout<<"Enter a binary number: ";
cin>>number;
cout<<endl;
BinaryToDecimal(number);
break;
case 3:
int decimalNumber;
cout<<"Enter a decimal number:";
cin>>decimalNumber;
cout<<endl;
DecimalToBinary(decimalNumber);
case 4:
choice = 1;
break;
default:
choice = 0;
}
} while (choice);
return 0;
}
//Write a program that will input letter grades (A, B, C, D, F), the number of
//which is input by the user (a maximum of 50 grades). The grades will be read
//into an array. A function will be called five times (once for each letter grade)
//and will return the total number of grades in that category. The input to the
//function will include the array, number of elements in the array and the letter
//category (A, B, C, D or F). The program will print the number of grades that
//are A, B, etc.
#include <iostream>
using namespace std;
double countGrade(char letterCategory, int size, char array);
const int SIZE = 5;
char letterCategory[SIZE] = {'A', 'B', 'C', 'D', 'F'};
char userLetters[50];
int main()
{
// Declare Variables
int numberOfGrades = 0;
int gradeNumbersA = 0;
int gradeNumbersB = 0;
int gradeNumbersC = 0;
int gradeNumbersD = 0;
int gradeNumbersF = 0;
// Get the number of grades to be read
cout << "Please input the number of grades to be read in. (1-50): ";
cin >> numberOfGrades;
// Input Validation
if(numberOfGrades < 1 || numberOfGrades > 50)
{
cout << "Error! Invalid Input. Please enter a number between 1 and 50.\n";
cin >> numberOfGrades;
}
while(numberOfGrades < 1 || numberOfGrades > 50);
cout << "All grades must be upper case A B C D or F.\n";
// Get the grade
{
for(int i = 0; i < numberOfGrades; i++)
{
cout << "Input a grade: ";
cin >> userLetters[i];
}
}
// Output the number in each category
cout << "Number of A: " << gradeNumbersA << endl;
cout << "Number of B: " << gradeNumbersB << endl;
cout << "Number of C: " << gradeNumbersC << endl;
cout << "Number of D: " << gradeNumbersD << endl;
cout << "Number of F: " << gradeNumbersF << endl;
return 0;
}
double countGrade(char letterCategory, int size, char array)
{
for(int count = 0; count < 5; count++)
{
int a = 0, b = 0, c = 0, d = 0, f = 0;
switch(array)
{
case 'A':
a++;
return a;
break;
case 'B':
b++;
return b;
break;
case 'C':
c++;
return c;
break;
case 'D':
d++;
return d;
break;
case 'F':
f++;
return f;
break;
}
}
}
I'm having trouble figuring this one out. I'm not quite sure how to call the countGrade function in the main function. I know I have messed up elsewhere in this program, but I would really appreciate help with that.
You don't need a switch statement. Just compare the grade in the array element with the grade in the parameter. And you shouldn't return the total until the end of the function. You're returning in the loop as soon as you match one grade, so you stop looping.
int countGrade(char letterCategory, int size, char array[]) {
int total = 0;
for (int count = 0; count < size; count++) {
if (array[count] == letterCategory) {
total++;
}
}
return total;
}
Then in main() you just do:
int numberOfGradesA = countGrade('A', numberOfGrades, userLetters);
and similarly for the other grades.
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string.h>
using namespace std;
int main()
{
char pin[6]; //character array to allow for ease of input
int randomNumbers[10]; //holding the randomized numbers that are printed back to the user
int pinStorage[5];
char pinVerify[5];
char pinReenter[6];
int result;
srand(time(0));
cout << "Enter your pin number" << endl;
cin >> pin;
for (int i = 0; i < 5; i++)
{
pinStorage[i] = pin[i] - '0';
}
for (int i = 0; i < 10; i++)
{
randomNumbers[i]= rand() % 3 + 1;
}
cout << "Pin Verify: ";
for (int b = 0; b < 5; b++)
{
for (int d = 0; d <10; d++)
{
if (pinStorage[b]== d)
{
pinVerify[b] = randomNumbers[d];
switch (pinVerify[b])
{
case 1: pinVerify[b] = '1';
break;
case 2: pinVerify[b] = '2';
break;
case 3: pinVerify[b] = '3';
}
cout << pinVerify[b] << " ";
}
}
}
cout << " " << endl;
cout << "Pin : 0 1 2 3 4 5 6 7 8 9" << endl;
cout << "Number: ";
for (int c = 0; c < 10; c++)
{
cout << randomNumbers[c] << " ";
}
cout << " " << endl;
cout << "Renter pin" << endl;
cin >> pinReenter;
for(int h = 0; h < 5; ++h)
{
int digit = pinStorage[h];
pinReenter[h] = randomNumbers[digit] + '0';
}
cout << "PV: " << pinVerify;
cout << "PR: " << pinReenter;
result = (strcmp(pinVerify, pinReenter));
switch(result)
{
case 1: cout << "You did not enter the pin correctly!" << endl;
break;
case 0: cout << "Pin Entered Correctly!" << endl;
break;
case -1: cout << "You did not enter the pin correctly!" << endl;
}
The above is my code. The objective is to be able to enter a normal 5 digit pin such as 12345. The program will then store that pin, and produce a screen like this:
Pin: 0 1 2 3 4 5 6 7 8 9
Num: 3 1 2 3 2 2 3 1 1 3
The program randomized the num part that you see and assigns it to the numbers above. That way the user reenters 12322 and the computer recognizes it as him entering the right code. The next time it where to do it, it would be rerandomized to something else. This whole project is designed to prevent shoulder surfing.
However I seem to be having a problem with my code. Almost everything is working but with the final strcmp function. Even though I have pinVerify set to 5, it still gives me 5 numbers and a ASCII character at the end, something like 21323☻. This makes it impossible to ever have pinVerify and pinReenter as equal, meaning it's impossible for the program to tell you you entered in the challenge correctly, even when you did.
Can anyone help me fix this? I've been looking and tinkering for a while and have been completely unsuccessful.
C-style strings are null-terminated. In your example, it means that, when you want to work with two strings of length 5, you should actually reserve 5+1=6 chars for each of them, and make sure that the 5-th (0-indexed) char contains a character with ASCII code 0. Otherwise, strcmp, and any other C-string function, proceeds past the end of your char[5] array until it finds a byte containing zero.