converting integer into char explictly - c++

I am trying to convert integer into character. I know how to convert character to integer like this int(a) where a is a character. But when I am trying to convert integer to character, it is giving me a symbolic value. Please help me out.
I am doing something like below. Thanks in advance.
int a=0;
char str1[20];
for(int i=0;i<size;i++)
//somecalculation that sets value in a everytime and stores in str1
str1[i]=char(a)-'A'
Well I am running for loop and setting values in str1. This is just little of my code.

You could use str1[i] = static_cast<char>(a + '0');. This will convert a = 0 to '0', a = 1 to '1' etc. Consider the behaviour as undefined outside the range 0, ..., 9.

just use sprintf:
for(int i=0;i<size;i++)
//somecalculation that sets value in a everytime and stores in str1
sprintf(str1 + i, "%i", a);
since you noted that a is each time only a one digit integer, this should work, but this is not very error prone... normally you should check on how much digits were written:
for(int i=0;i<size;i++)
//somecalculation that sets value in a everytime and stores in str1
if (sprintf(str1 + i, "%i", a) != 1)
printf("expected to print only one character!\n");

Related

How to sort non-numeric strings by converting them to integers? Is there a way to convert strings to unique integers while being ordered?

I am trying to convert strings to integers and sort them based on the integer value. These values should be unique to the string, no other string should be able to produce the same value. And if a string1 is bigger than string2, its integer value should be greater. Ex: since "orange" > "apple", "orange" should have a greater integer value. How can I do this?
I know there are an infinite number of possibilities between just 'a' and 'b' but I am not trying to fit every single possibility into a number. I am just trying to possibly sort, let say 1 million values, not an infinite amount.
I was able to get the values to be unique using the following:
long int order = 0;
for (auto letter : word)
order = order * 26 + letter - 'a' + 1;
return order;
but this obviously does not work since the value for "apple" will be greater than the value for "z".
This is not a homework assignment or a puzzle, this is something I thought of myself. Your help is appreciated, thank you!
You are almost there ... just a minor tweaks are needed:
you are multiplying by 26
however you have letters (a..z) and empty space so you should multiply by 27 instead !!!
Add zeropading
in order to make starting letter the most significant digit you should zeropad/align the strings to common length... if you are using 32bit integers then max size of string is:
floor(log27(2^32)) = 6
floor(32/log2(27)) = 6
Here small example:
int lexhash(char *s)
{
int i,h;
for (h=0,i=0;i<6;i++) // process string
{
if (s[i]==0) break;
h*=27;
h+=s[i]-'a'+1;
}
for (;i<6;i++) h*=27; // zeropad missing letters
return h;
}
returning these:
14348907 a
28697814 b
43046721 c
373071582 z
15470838 abc
358171551 xyz
23175774 apple
224829626 orange
ordered by hash:
14348907 a
15470838 abc
23175774 apple
28697814 b
43046721 c
224829626 orange
358171551 xyz
373071582 z
This will handle all lowercase a..z strings up to 6 characters length which is:
26^6 + 26^5 +26^4 + 26^3 + 26^2 + 26^1 = 321272406 possibilities
For more just use bigger bitwidth for the hash. Do not forget to use unsigned type if you use the highest bit of it too (not the case for 32bit)
You can use position of char:
std::string s("apple");
int result = 0;
for (size_t i = 0; i < s.size(); ++i)
result += (s[i] - 'a') * static_cast<int>(i + 1);
return result;
By the way, you are trying to get something very similar to hash function.

setting char arrays equal to eachother with isdigit and isalpha

Im trying to set a char array equal to 2 other arrays depending on if the element in the first array is a number or a letter. The code makes logical sense to me but the output for the 2 other strings after the for loop doesn't correspond to the logic. Is it because of a missing null value somewhere in the other 2 loops or is the code itself invalid? arrayAlpha, arrayNum, and palind are all char arrays set to a length of 30 elements while string length was already determined before the for loop began.
for(int k=0; k<=stringLength; k++)
{
if( isalpha(palind[k])){
arrayAlpha[k]=palind[k];}
if ( isdigit(palind[k]))
{
arrayNum[k]=palind[k];
}
}
Given the input:
char palind[30] = "12345abcde";
arrayAlpha is garbage.
arrayNum is "12345"
However,
char palind[30] = "abcde12345";
arrayAlpha is "abcde".
arrayNum is garbage.
Thus, [k] is the problem when used in your arrayNum or arrayAlpha which doesn't start with 0.
Simple change will just be subtracting the length of the other.
arrayAlpha[k - strlen(arrayNum)] = palind[k];
arrayNum[k - strlen(arrayAlpha)] = palind[k];
since lengthOfPalind = lengthOfArrayAlpha + lengthOfArrayNum assuming palind only contains letters or numbers.

String not modified by loop

I'm solving the following problem:
The assignment is to create and return a string object that consists of digits in an int that is sent in through the function's parameter; so the expected output of the function call string pattern(int n) would be "1\n22\n..n\n".
In case you're interested, here is the URL (You need to be signed in to view) to the full assignment, a CodeWars Kata
This is one of the tests (with my return included):
Test-case input: pattern(2)
Expected:
1
22
Actual: "OUTPUT"
//string header file and namespace are already included for you
string pattern(int n){
string out = "OUTPUT";
for (int i = 1; i <= n; ++i){
string temp = "";
temp.insert(0, i, i);
out += temp;
}
return out;
}
The code is self-explanatory and I'm sure there are multiple ways of making it run quicker and more efficiently.
My question is two-fold. Why doesn't my loop start (even though my expression should hold true (1 <= 2) for above case)?
And how does my code hold in the grand scheme of things? Am I breaking any best-practices?
The overload of std::string::insert() that you are using takes three arguments:
index
count
character
You are using i as both count and character. However, the function expects the character to be of char type. In your case, your i is interpreted as a character with the code of 1 and 2, which are basically spaces (well, not really, but whatever). So your output really looks like OUTPUT___ where ___ are three spaces.
If you look at the ascii table, you will notice that digits 0123...9 have indexes from 48 to 57, so to get an index of a particular number, you can do i + 48, or i + '0' (where '0' is the index of 0, which is 48). Finally, you can do it all in the constructor:
string temp(i, i + '0');
The loop works - but does nothing visible. You insert the character-code 1 - not the character '1'; use:
temp.insert(0, i, '0'+i);
the insert method is not called right:
temp.insert(0, i, i); --->
temp.insert(0, i, i+'0');

Shift cipher in C++ (How to get ASCII value and handling numbers)

I have a program set up already to read in a file and split each line into words, storing them into a double vector of strings. That is,
std::vector < std::vector <std::string> > words
So, the idea is to use an array from alphabet a-z and using the ASCII values of the letters to get the index and swapping the characters in the strings with the appropriate shifted character. How would I get the value of each character so that I can look it up as an index?
I also want to keep numbers intact, as a shift cipher, I believe, doesn't do anything with numbers in the text to be deciphered. How would I check if the character is an int so I can leave it alone?
If you want the ASCII value, you simply have to cast the value to a int:
int ascii_value = (int)words[i][j][k];
If you want to have a value starting from A or a you can do this:
int letter_value_from_A = (int)(words[i][j][k] - 'A');
int letter_value_from_a = (int)(words[i][j][k] - 'a');
Your char is nothing else than a value. Take this code as example (I am used to program C++11, so this will be a little ugly):
char shiftarray[256] = {0, 0, 0, 0 // Here comes your map //
std::string output;
for(int w=0; w<words.length(); w++)
{
for(int c=0; c<words[w].length(); c++)
{
output.pushback(shiftarry[words[w][c]]);
}
output.push_back(' ');
}
I do not know how to do it in anything other than basic, but very simply get the ascii value of each letter in the string using a loop. As the loop continues add a value to, or subtract a value from the ascii value you just obtained, then convert it back to a letter and append it to a string. This will give you a different character than you had originally. By doing this, you can load and save data that will look like gibberish if anyone tried to view it other than in the program it was written in. The data then becomes a special propriatry document format.

C++ - Overloading operator>> and processing input using C-style strings

I'm working on an assignment where we have to create a "MyInt" class that can handle larger numbers than regular ints. We only have to handle non-negative numbers. I need to overload the >> operator for this class, but I'm struggling to do that.
I'm not allowed to #include <string>.
Is there a way to:
a. Accept input as a C-style string
b. Parse through it and check for white space and non-numbers (i.e. if the prompt is cin >> x >> y >> ch, and the user enters 1000 934H, to accept that input as two MyInts and then a char).
I'm assuming it has something to do with peek() and get(), but I'm having trouble figuring out where they come in.
I'd rather not know exactly how to do it! Just point me in the right direction.
Here's my constructor, so you can get an idea for what the class is (I also have a conversion constructor for const char *.
MyInt::MyInt (int n)
{
maxsize = 1;
for (int i = n; i > 9; i /= 10) {
// Divides the number by 10 to find the number of times it is divisible; that is the length
maxsize++;
}
intstring = new int[maxsize];
for (int j = (maxsize - 1); j >= 0; j--) {
// Copies the integer into an integer array by use of the modulus operator
intstring[j] = n % 10;
n = n / 10;
}
}
Thanks! Sorry if this question is vague, I'm still new to this. Let me know if I can provide any more info to make the question clearer.
So what you basically want is to parse a const char* to retrieve a integer number inside it, and ignore all whitespace(+others?) characters.
Remember that characters like '1' or 'M' or even ' ' are just integers, mapped to the ASCII table. So you can easily convert a character from its notation human-readable ('a') to its value in memory. There are plenty of sources on ascii table and chars in C/C++ so i'll let you find it, but you should get the idea. In C/C++, characters are numbers (of type char).
With this, you then know you can perform operations on them, like addition, or comparison.
Last thing when dealing with C-strings : they are null-terminated, meaning that the character '\0' is placed right after their last used character.