I'm wanting to take the input of a user (mathematic expression) and push it onto a stack. Then I want to run it through some rules which ask if its a '(', a number, or an operator '+'. My problem is so far I don't know how to tell, specifically stating inside the while loop's first if statement, if a char is "actually" a number. Any suggestions?
#include <stack>
int main()
{
std::stack<char> myStack; // initializing the stack
char line[40];
cin.getline(line, 40); // this and the proceeding line get the input
for (int i = 0; i < 40; i++)
myStack.push(line[i]); //pushing all of the char onto the stack.
while (!myStack.empty()) {
if (myStack item = a number) {
// ^ this is where it doesn't compile.
// I need to figure out how to find out if a char is a number
cout << item << endl;
}
else if (myStack.empty()) {
myStack.push(item);
}
}
}
There's a function is C++ called isdigit, it checks if a character is a decimal digit.
if(isdigit(your_char)) //Then it's a number
Use the isdigit function:
isdigit(x)
There is a function called isdigit() in the stdlib that will answer this question for you.
There is no magic to it, however. Digits, in ASCII, are just chars in the range 48-57, 48 being '0' and 57 being '9'.
char isdigit(char d) {
return (d >= 48) && (d <= 57);
}
Based on your question, if all you want is to find if a char is a number or not. Please cast it to int and check if it is between the ascii values of 48 and 57, both included.
bool CheckIfNum(char chartToCheck)
{
int aciiOfChar = (int) charToCheck;
if (asciiOfChar >= 48 && asciiOfChar <= 57)
return true;
return false;
}
you can also use std::isdigit function
Related
#include<iostream>
#include<string>
using namespace std;
string pass(string a){
int i=0;
string c[100];
char d;
while(a[i]!='\0'){
d = a[i];
if(d>='a'&& d<='z'){
d++;
c[i]=d;
}
else if(d>='A' && d<='Z'){
d++;
c[i]=d;
}
else{
c[i]=d;
}
i++;
}
for(int k=0; k<i; k++){
cout<<c[k];
}
}
int main(){
string x;
getline(cin,x);
pass(x);
return 0;
}
This is my solution.
I was looking for this kind of problem for a while but all I got was for pre-defined inputs. So, I passed a string from the main function.
I used a while loop to store every letter with the following letter (EX "a -> b") in another array "c". I then print the copied array using a loop.
Can we make it shorter?
You don't need to create a separate array called c. You can create an output string and iterate through it and increment the characters as shown below:
int main()
{
std::string input;
std::getline(std::cin, input);
std::string output(input);
for(char &c: output)
{
++c;
}
std::cout<<"input was: "<<input<<std::endl;
std::cout<<"changed string is: "<<output<<std::endl;
}
This is probably a better (and shorter) implementation for your code:
#include<iostream>
#include<string>
char NextAlpha(char character)
{
if (character == 'Z') return 'A';
else if (character == 'z') return 'a';
return character + 1; // Can be replaced by 'char((int)character + 1);'
}
int main() {
std::string input;
getline(std::cin, input);
for (int i = 0; i < input.size(); i++)
{
input[i] = NextAlpha(input[i]);
}
std::cout << input;
return 0;
}
The NextAlpha function returns the next alphabet by adding 1 to the character, but a more understandable version of it will be firstly converting the given character into an int as such:
(int)character
..which basically means getting the ascii value of that character. Now we add 1 to the int:
(int)character + 1
..and then convert it back to char
char((int)character + 1)
..but here I've not used this way because ++character looks a lot more cleaner.
The exceptions are defined before the return statement.
In the main function, we have a loop that iterates through all of the characters in the given string, and for each character, it does the following:
// Set the character at index 'i' of string 'input' to the next character in the alphabet.
input[i] = NextAlpha(input[i]);
Also, consider not using the following in your code:
using namespace std;
..as it's considered as bad practice.
First, you have an error in your code: your pass function is declared as returning a string but it doesn't return anything. Actually, you don't need to return anything – just pass the string by reference and make any required changes to its content "in place".
Second, you should be aware that the C++ Standard does not require that the Latin letters (lower- and upper-case) be represented by contiguous, sequential values (though in the ASCII system, used in most implementations today, they are).1
Third, you don't need so many loops, and you don't need to repeat the c[i]=d; statement in the if, else if and else blocks.
I'm not sure what you want to do with the 'z' and 'Z' characters but, in the code below, I'm assuming these should "wrap around", to 'a' and 'A', respectively.
So, here's a way to do what you want more concisely, and which doesn't depend on the implementation's specific representation values for Latin letters:
#include<iostream>
#include<string>
void pass(std::string& a) // Pass by reference (using "&") - changes will be kept.
{
const std::string Lowers{ "abcdefghijklmnopqrstuvwxyz" };
const std::string Uppers{ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" };
size_t p;
for (auto& c : a) { // Note the "&" again: changes to c will be reflected in the corresponding "a" element
if ((p = Lowers.find(c)) != std::string::npos) {
c = Lowers[++p % 26]; // 'z' wraps round to 'a'
}
if ((p = Uppers.find(c)) != std::string::npos) {
c = Lowers[++p % 26]; // 'Z' wraps round to 'A'
}
}
}
int main()
{
std::string x;
std::getline(std::cin, x);
pass(x);
std::cout << x << std::endl;
return 0;
}
I have moved the output of the transformed string to the main function (and simplified it somewhat); generally, a function should do only the task it is set – which, in this case is to make the transformation. The subsequent display of the transformed string should be left to the calling module.
1 The EBCDIC system, for example, doesn't have the Latin letters in a contiguous sequence. You could use the std::islower(), std::isupper() and/or std::isalpha() functions to check for letters, but you would still need some sort of "data table" to determine what the 'next' character should be, unless you assume an ASCII or compatible encoding system.
Please help me to identify the error in this program, as for me it's looking correct,I have checked it,but it is giving wrong answers.
In this program I have checked explicitly for A,B,C,D,E,F,and according to them their respective values.
[Edited]:Also,this question relates to how a character number is converted to actual integer number.
#include<iostream>
#include<cmath>
#include<bits/stdc++.h>
using namespace std;
void convert(string num)
{
long int last_digit;
int s=num.length();
int i;
long long int result=0;
reverse(num.begin(),num.end());
for(i=0;i<s;i++)
{
if(num[i]=='a' || num[i]=='A')
{
last_digit=10;
result+=last_digit*pow(16,i);
}
else if(num[i]=='b'|| num[i]=='B')
{
last_digit=11;
result+=last_digit*pow(16,i);
}
else if(num[i]=='c' || num[i]=='C')
{
last_digit=12;
result+=last_digit*pow(16,i);
}
else if(num[i]=='d'|| num[i]=='D' )
{
last_digit=13;
result+=last_digit*pow(16,i);
}
else if(num[i]=='e'|| num[i]=='E' )
{
last_digit=14;
result+=last_digit*pow(16,i);
}
else if(num[i]=='f' || num[i]=='F')
{
last_digit=15;
result+=last_digit*pow(16,i);
}
else {
last_digit=num[i];
result+=last_digit*pow(16,i);
}
}
cout<<result;
}
int main()
{
string hexa;
cout<<"Enter the hexadecimal number:";
getline(cin,hexa);
convert(hexa);
}
Your code is very convoluted and wrong.
You probably want this:
void int convert(string num)
{
long int last_digit;
int s = num.length();
int i;
long long int result = 0;
for (i = 0; i < s; i++)
{
result <<= 4; // multiply by 16, using pow is overkill
auto digit = toupper(num[i]); // convert to upper case
if (digit >= 'A' && digit <= 'F')
last_digit = digit - 'A' + 10; // digit is in range 'A'..'F'
else
last_digit = digit - '0'; // digit is (hopefully) in range '0'..'9'
result += last_digit;
}
cout << result;
}
But this is still not very good:
the function should return a long long int instead of printing the result
a few other thing can be done mor elegantly
So a better version would be this:
#include <iostream>
#include <string>
using namespace std;
long long int convert(const string & num) // always pass objects as const & if possible
{
long long int result = 0;
for (const auto & ch : num) // use range based for loops whenever possible
{
result <<= 4;
auto digit = toupper(ch);
long int last_digit; // declare local variables in the inner most scope
if (digit >= 'A' && digit <= 'F')
last_digit = digit - 'A' + 10;
else
last_digit = digit - '0';
result += last_digit;
}
return result;
}
int main()
{
string hexa;
cout << "Enter the hexadecimal number:";
getline(cin, hexa);
cout << convert(hexa);
}
There is still room for more improvements as the code above assumes that the string to convert contains only hexadecimal characters. Ideally a check for invalid characters should be done somehow. I leave this as an exercise.
The line last_digit = digit - 'A' + 10; assumes that the codes for letters A to F are contiguous, which in theory might not be the case. But the probability that you'll ever encounter an encoding scheme where this is not the case is close to zero though. The vast majority of computer systems in use today use the ASCII encoding scheme, some use EBCDIC, but in both of these encoding schemes the character codes for letters A to F are contiguous. I'm not aware of any other encoding scheme in use today.
Your problem is in the elsecase in which you convert num[i] from char to its ascii equivalent. Thus, for instance, if you try to convert A0, the 0is converted into 48 but not 0.
To correct, you should instead convert your num[i] into its equivalent integer (not in asci).
To do so, replace :
else {
last_digit=num[i];
result+=last_digit*pow(16,i);
with
else {
last_digit = num[i]-'0';
result+=last_digit*pow(16,i);
}
In the new line, last_digit = num[i]-'0'; is equivalent to last_digit = (int)num[i]-(int)'0';which substracts the representation code of any one-digit-number from num[i] from the representation code of '0'
It works because the C++ standard guarantee that the number representation of the 10 decimal digits are contiguous and in incresing order (official ref iso-cpp and is stated in chapter 2.3 and paragraph 3
Thus, if you take the representation (for instance the ascii code) of any one-digit-number num[i] and substract it with the representation code of '0' (which is 48 in ascii), you obtain directly the number itself as an integer value.
An example of execution after the correction would give:
A0
160
F5
245
A small codereview:
You are repeating yourself with many result+=last_digit*pow(16,i);. you may do it only once at the end of the loop. But that's another matter.
You are complicating the problem more than you need to (std::pow is also kinda slow). std::stoul can take a numerical base and automatically convert to an integer for you:
#include <string>
#include <iostream>
std::size_t char_count{0u};
std::string hexa{};
std::getline(std::cin, hexa);
hexa = "0x" + hexa;
unsigned long value_uint = std::stoul(hexa, &char_count, 16);
So, I'm still new on coding, and my friend is kindly taught me a lot and I want to be learn it quick, then he gave me this exercise to study in my home
He gave me this question about booking table number, so I tried to make it..
But I'm having trouble with this part checking the table number if it is a digit or not... I was searching on google on how, but they only give example on how to do it with single character.. So, I made an account then ask here xD
btw, the table max number is 25.
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<ctype.h>
bool checkDigit(char tablenum){
char digit[3];
int n;
int value = tablenum;
if(tablenum>0 && tablenum<10)
n=1;
if(tablenum>9 && tablenum < 26)
n=2;
for(int i=0;i<n;i++){
digit[i] = value%10;
value /= 10;
}
if(n==1){
printf("digit 0 = %d\nisdigit = %d\n",tablenum,isdigit(tablenum)); //just checking the isdigit value
if(isdigit(digit[0])!=0){
puts("It's digit");
return true;
}
else{
puts("It's not digit");
return false;
}
}
if(n==2){
printf("digit 0 = %d isdigit 0 = %d \ndigit 1 = %d isdigit 1 = %d\n",digit[0],isdigit(digit[0]),digit[1],isdigit(digit[1])); //checking the values too
if(isdigit(digit[0]) != 0 && isdigit(digit[1]) != 0){
puts("It's digits!");
return true;
}
else{
puts("It's not digits!");
return false;
}
}
else{
printf("It's not digit!")
return false;
}
}
int main(){
int num;
bool itsdigit;
do{
scanf("%d",&num);fflush(stdin);
itsdigit = checkDigit(num);
} while(itsdigit != 1 );
getchar();
return 0;
}
Input = "25" "1" "0" "test"
Output = "It's a digit" "It's a digit" "It's not a digit" "
Since the table is only 1 to 25
When I input "1" on it shows the right digit, but when it when in to isdigit() I keep getting 0.
I wonder what when wrong with this, and please give explanation.
And thanks before!
You have multiple problems.
Lets start by taking a closer look at these two lines:
checkDigit(num);
itsdigit = checkDigit;
The first line calls checkDigit but throws away the result.
The second line does not call the function, instead the compiler will let it decay to a pointer to the function and assign that pointer to itsdigit. Your compiler should have complained about it.
Furthermore, isdigit doesn't have to return 1 when the character is a digit, it only have to return something which is non-zero.
Lastly, in the digits array you don't store characters, you store integer values. isdigit(1) will be false while isdigit('1') will be true. Just because you use the type char doesn't automatically store characters in the variables. And considering that you read an integer, and store its digits in the digits array, there's no need to check if the digits are actually digits. Of course the digits will be digits.
You probably want this:
bool IsOnlyDigits(const char text[])
{
int length = strlen(text);
for (int i = 0; i < length; i++)
{
if (!isdigit(text[i]))
return false;
}
return true;
}
int main() {
char num[50];
scanf("%s", num);
if (IsOnlyDigits(num))
puts("It's digits!");
else
puts("It's not digits!");
fflush(stdout);
getchar();
return 0;
}
Disclaimer: non error checking and non bounds checking code. #includes omitted for brevity. Is has been tested under Visual Studio 2015 and seems to be working fine here.
Examples of input and output:
123
It's digits!
12a
It's not digits!
abc
It's not digits!
To understand this, you need to learn about strings and arrays. Just read the corrsponding chapters in your C textbook.
You could instead create an array of type char or int, iterate through the array and check if any character instance is a digit or not using the isdigit() function.
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char arr[10];
cin>>arr;
for(int i=0;i<strlen(arr);i++){
if(isdigit(arr[i])){
cout<<arr[i]<<" is a digit\n";
}
else {
cout<<arr[i]<<" is not a digit\n";
}
}
return 0;
}
This is a task from school, I am supposed to write a recursive function that will convert a given int to a string, I know I'm close but I can't point the missing thing in my code, hints are welcome.
void intToStr(unsigned int num, char s[])
{
if (num < 10)
{
s[0] = '0' + num;
}
else
{
intToStr(num/10, s);
s[strlen(s)] = '0' + num%10;
}
}
Edit: my problem is that the function only works for pre initialized arrays, but if I let the function work on an uninitialized function it will not work.
Unless your array is zero-initialized, you are forgetting to append a null terminator when you modify it.
Just add it right after the last character:
void intToStr(unsigned int num, char s[])
{
if (num < 10)
{
s[0] = '0' + num;
s[1] = 0;
}
else
{
intToStr(num/10, s);
s[strlen(s)+1] = 0; //you have to do this operation here, before you overwrite the null terminator
s[strlen(s)] = '0' + num%10;
}
}
Also, your function is assuming that s has enough space to hold all the digits, so you better make sure it does (INT_MAX is 10 digits long I think, so you need at least 11 characters).
Andrei Tita already showed you the problem you had with the NULL terminators. I will show you an alternative, so you can compare and contrast different approaches:
int intToStr(unsigned int num, char *s)
{
// We use this index to keep track of where, in the buffer, we
// need to output the current character. By default, we write
// at the first character.
int idx = 0;
// If the number we're printing is larger than 10 we recurse
// and use the returned index when we continue.
if(num > 9)
idx = intToStr(num / 10, s);
// Write our digit at the right position, and increment the
// position by one.
s[idx++] = '0' + (num %10);
// Write a terminating NULL character at the current position
// to ensure the string is always NULL-terminated.
s[idx] = 0;
// And return the current position in the string to whomever
// called us.
return idx;
}
You will notice that my alternative also returns the final length of the string that it output into the buffer.
Good luck with your coursework going forward!
I'm creating a Caesar Cipher in c++ and i can't figure out how to increment a letter.
I need to increment the letter by 1 each time and return the next letter in the alphabet. Something like the following to add 1 to 'a' and return 'b'.
char letter[] = "a";
cout << letter[0] +1;
This snippet should get you started. letter is a char and not an array of chars nor a string.
The static_cast ensures the result of 'a' + 1 is treated as a char.
> cat caesar.cpp
#include <iostream>
int main()
{
char letter = 'a';
std::cout << static_cast<char>(letter + 1) << std::endl;
}
> g++ caesar.cpp -o caesar
> ./caesar
b
Watch out when you get to 'z' (or 'Z'!) and good luck!
It works as-is, but because the addition promotes the expression to int you want to cast it back to char again so that your IOStream renders it as a character rather than a number:
int main() {
char letter[] = "a";
cout << static_cast<char>(letter[0] + 1);
}
Output: b
Also add wrap-around logic (so that when letter[0] is z, you set to a rather than incrementing), and consider case.
You can use 'a'+((letter - 'a'+n)%26);
assuming after 'z' you need 'a' i.e. 'z'+1='a'
#include <iostream>
using namespace std;
int main()
{
char letter='z';
cout<<(char)('a' + ((letter - 'a' + 1) % 26));
return 0;
}
See this https://stackoverflow.com/a/6171969/8511215
Does letter++ work?
All in all char is a numeric type, so it will increment the ascii code.
But I believe it must be defined as char letter not an array. But beware of adding one to 'Z'. You will get '[' =P
#include <iostream>
int main () {
char a = 'a';
a++;
std::cout << a;
}
This seems to work well ;)
char letter = 'a';
cout << ++letter;
waleed#waleed-P17SM-A:~$ nano Good_morning_encryption.cpp
waleed#waleed-P17SM-A:~$ g++ Good_morning_encryption.cpp -o Good_morning_encryption.out
waleed#waleed-P17SM-A:~$ ./Good_morning_encryption.out
Enter your text:waleed
Encrypted text:
jnyrrq
waleed#waleed-P17SM-A:~$ cat Good_morning_encryption.cpp
#include <iostream>
#include <string>
using namespace std;
int main() {
//the string that holds the user input
string text;
//x for the first counter than makes it keeps looping until it encrypts the user input
//len holds the value (int) of the length of the user input ( including spaces)
int x, len;
//simple console output
cout << "Enter your text:";
//gets the user input ( including spaces and saves it to the variable text
getline(cin, text);
//give the variable len the value of the user input length
len = (int)text.length();
//counter that makes it keep looping until it "encrypts" all of the user input (that's why it keeps looping while its less than len
for(x = 0; x < len; x++) {
//checks each letts (and spaces) in the user input (x is the number of the offset keep in mind that it starts from 0 and for example text[x] if the user input was waleed would be w since its text[0]
if (isalpha(text[x])) {
//converts each letter to small letter ( even though it can be done another way by making the check like this if (text[x] =='z' || text[x] == 'Z')
text[x] = tolower(text[x]);
//another counter that loops 13 times
for (int counter = 0; counter < 13; counter++) {
//it checks if the letts text[x] is z and if it is it will make it a
if (text[x] == 'z') {
text[x] = 'a';
}
//if its not z it will keeps increamenting (using the loop 13 times)
else {
text[x]++;
}
}
}
}
//prints out the final value of text
cout << "Encrypted text:\n" << text << endl;
//return 0 (because the the main function is an int so it must return an integer value
return 0;
}
Note: this is called caeser cipher encryption it works like this :
ABCDEFGHIJKLMNOPQRSTUVWXYZ
NOPQRSTUVWXYZABCDEFGHIJKLM
so for example my name is waleed
it will be written as : JNYRRQ
so its simply add 13 letters to each letter
i hope that helped you
It works but don't forget that if you increment 'z' you need to get 'a' so maybe you should pass by a check function that output 'a' when you get 'z'.
cast letter[n] to byte* and increase its referenced value by 1.