change ascii code and preappend character to string in C++ - c++

I want to pre-append a character to a string after performing some calculations to the character ascii code but doing (somenumber+'0') + s doesn't work and I don't understand why.
the answer I want is "ahello" using the ascii representation of a ('0' + 49)
This is what I have tried:
std::string s = "hello";
s.insert(0, std::to_string('a'));
std::cout << s << std::endl; // 97hello
s = "hello";
s += 'a';
std::cout << s << std::endl; // helloa
s = "hello";
s = 'a' + s;
std::cout << s << std::endl; // ahello
//s = (49+'0') + s;
//std::cout << s << std::endl;

Do you want to append the ASCII code int of the character (97) or do you want to append the ASCII representation ('a') ?
In the later case, you could just use s.insert(0, "a") directly.
If you want to transform the ASCII code int before, you can use the std::string fill constructor, as was already pointed out by Steephen:
// fills the string with n consecutive copies of character c.
std::string(size_t n, char c);
// so you could do this to get a string "f":
std::string(1, 'a'+5);

This will solve the issue:
s.insert(0, string(1,1+'a'));
O/p
bhello
s.insert(0, string(1,0+'a'));
O/P
ahello

Try
s.insert(0, string(1,49+'a'));

Related

Issues replacing a char within a c++ string using string.replace()

I am writing a program that uses a substitution cipher.
I am trying to replace each char in a string (that the user entered) with a char from another string (the encryption key string).
But I am having a bunch of issues doing this with the string.replace() function. It does not replace the the char in the userMessage with the correct char. Although this is not an issue when using a string literal as initialization value for letterReplacement. In addition to this, it somehow temporarily increases the size of the userMessage resulting in the loop running for e.g 5 times in a message 3 char long (no matter how letterReplacement was initialized). I would appreciate any information on why this happens.
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::string userMessage;
std::cout << "\nWelcome to my Military Grade* Encryption Software!" << std::endl;
std::cout << "--------------------------------------------------" << std::endl << std::endl;
std::cout << "Please enter a secret message you would like to encrypt:\n-" << std::endl;
getline(std::cin, userMessage);
std::cout << "-" << std::endl << std::endl;
const std::vector <std::string> encryptionKey {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZT.,<>!?+- '",
"ß?pl ,;0=}okm9)]ijN8([uhb7/{zgv6&ctf%xdrys4$e3w|<2Q>1!+#ä-:*GnB"};
for(size_t i {0}; i < userMessage.size(); ++i) // Here we encrypt the Message
{
char currentCharInUM {userMessage.at(i)};
size_t currentKeyPosition {encryptionKey.at(0).find(currentCharInUM)}; //finds the position that currentChar is at in first encryptionKey String
std::cout << "currentKeyPosition: " << currentKeyPosition << " - " << i << std::endl;
if(currentKeyPosition == std::string::npos) // is letter in userMessage is not in encryptionKey just keep it (skip iteration)
continue;
std::string letterReplacement {encryptionKey.at(1).at(currentKeyPosition)};
userMessage.replace(i,1,letterReplacement);
}
std::cout << userMessage;
return 0;
}
The first character of 2nd element of the vector encryptionKey 'ß' is equal to 2 bytes. So that when you enter 'a' it returns '├' and when you enter b it returns 'ş'. You can try to put another character instead of 'ß'.
If your intention was indeed to store non-ASCII characters, it would have been more advantageous to use a lookup table.
The table could be a std::unordered_map<char, wchar_t> to map the English letters to the encrypted characters:
#include <iostream>
#include <string>
#include <unordered_map>
int main()
{
// Strings
const char encryptionKeyA[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZT.,<>!?+- '";
const wchar_t encryptionKeyW[] = L"ß?pl ,;0=}okm9)]ijN8([uhb7/{zgv6&ctf%xdrys4$e3w|<2Q>1!+#ä-:*GnB";
// Create the lookup table bassed on the above strings
std::unordered_map<char, wchar_t> encryptionMap;
for (int i = 0; i < sizeof(encryptionKeyA); ++i)
encryptionMap[encryptionKeyA[i]] = encryptionKeyW[i];
// Test
std::string userMessage = "abcTest";
// The output string
std::wstring encryptedString;
// Now go through each character of the userMessage
for(auto ch : userMessage)
{
// If the character exists, append the associated encrypted character
auto iter = encryptionMap.find(ch);
if (iter != encryptionMap.end())
encryptedString += iter->second;
else
encryptedString += L' '; // Just append a space if it didn't exist
}
std::wcout << encryptedString;
}
Output:
ss?p1 N8
Note that the output is what is displayed if the locale is English. If the terminal/output were set to German, I would assume that the output would be:
ß?p1 N8
since the first character is the "double-s".
Also note that I am assuming that both the original and encrypted character strings are of the same size (in terms of the number of characters) when building the map. If they're not the same size, then the loop to build the map should be adjusted accordingly.

how can I strcat one character to array character in c++

I want to get one character from cin.get() and add it to a array character. I use strcat but the single character has an error. please help me if you know. thanks for all answers.
void main (void)
{
char e[80]="hi";
char c;
cin.get(c);
strcat(e,c);
cout << "e: " << e << endl;
getch();
}
This is part of my code that I want to do this.
stncat() concatenates two strings, method signature looks like this,
char * strncat ( char * destination, const char * source, size_t num );
but you are trying to concatenate a char which is not right!
As you are using C++, it is safe and easy to do it in C++ style rather than using C style.So use
std::string cAsStr(c); // Make the string
e += aAsStr; // + operator does the concatenation
If you are desperate to do it in the C style, use:
char cAsStr[] = { c, '\0' }; // Making a C-style string
strcat(e, cAsStr); // Concatenate
Change strcat(e,c) to strncat(e, &c, 1)
A little change to your code would do it.
char e[80]="hi";
char c[2] = {0}; // This is made as an array of size 2
cin.get(c[0]); // Character is read into the first position.
strcat(e,c);
cout << "e: " << e << endl;
char s[] = { c, 0 };
strcat(e, s);
But please, just use std::string:
string e="hi";
char c;
cin.get(c);
e += c;
cout << "e: " << e << endl;

atoi() Not Working with std::string::substr()

This is a snippet of my code:
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h> // atoi()
int main() {
std::string line;
std::ifstream numbers("numbertest.txt");
if (numbers.is_open()) {
while (std::getline(numbers, line)) {
for (int i = 0; i < line.length() - 4; i++) {
for (int n = 0; n < 5; n++) {
std::cout << atoi((line.substr(i, 5)[n]).c_str());
}
I want to operate with numbers in groups of 5, from a file. Why is atoi() not working here? It says "expression must have class type" under the second parentheses on the atoi line.
line.substr(i, 5) creates a temporary std::string containing 5 characters in line from position i
std::string foo = "hello world";
int i = 2;
std::cout << foo.substr(2, 5) << '\n';
would print "llo wo".
The [n] operator returns the nth character of the substring, which is of type char, you are then calling .c_str() on that character rather than on the substring.
You can avoid the .c_str() entirely by using std::stoi, e.g.
std::cout << "line.substr(i, 5) = " << line.substr(i, 5) << '\n';
std::cout << std::stoi(line.substr(i, 5));
aoti and stoi both take a string representation of a number as their input and return the numeric value. For example:
std::string input = "123a";
// std::cout << input * 10 << '\n'; // illegal: input is a string, not a number.
int i = std::stoi(input); // converts to integer representation, i.e. 123
std::cout << i * 10 << '\n'; // outputs 1230
----- EDIT -----
You're actually asking all the wrong questions. What you want to do is take an input pattern and output all of the patterns of 5 characters in it.
Example input: "1020304050"
Example output: 10203 02030 20304 03040 30405 04050
You don't need to convert these to numbers to output them, you can just output the characters. The problem with your original code wasn't the conversion it was the incorrect sequence of operators.
std::substring is expensive, it has to create a new, temporary string, copy characters from the original into it, and then return it, and it does it for every call.
The following should achieve what you're trying to do:
while (std::getline(numbers, line)) {
for (size_t i = 0; i < line.length() - 4; i++) {
for (size_t n = 0; n < 5; n++) {
std::cout << line[i + n];
}
std::cout << '\n';
}
}
If you really want to invoke substr, you could also implement this as
while (std::getline(numbers, line)) {
for (size_t i = 0; i < line.length() - 4; i++) {
std::cout << line.substr(i, 5) << '\n';
}
}
Here's a working demonstration: http://ideone.com/mXv2z5
Try atoi( line.substr(i,5).c_str() )
Or if you want for each character
std::cout << ((line.substr(i, 5)[n]) - '0');
Or even better
std::cout << (line[i+n]) - '0');
Note that: atoi is not ascii to integer. It converts a ctype string to number. For a single character, this conversion should be done using arithmetic or lookup table.
Also there is no point converting characters to integer and then print it (back to chacters). You should better print digit character itself.
Moreover in C++, I would prefer to use stringstream instead or atoi. On C++11 there are even more advanced solutions like sto*.

hex char to decimal and store output as char

I am writing a hex to dec conversion function. The input is a single character which is converted to hex and returned back as a char.
Here is the function
char hex2dec(char inp)
{
char out;
cout << "inp:" << inp;
if(inp >= '0' && inp <='9')
{
out = (inp - '0');
cout << " out " << out;
}
else
{
out = (toupper(inp) - 'A' + 10);
cout << " out " << out;
}
return out;
}
When i pass '0' and 'A' to the function, the print i get is
inp:0 out
inp:A out
i.e nothing is printed in out.
I am not able to find the issue..Can anyone help?
What you are actually trying to print is ascii characters with codes [0-15] which are not printable characters ie you want to print 15 but you print "\x0f" etc
use:
cout << (int)out;
and you'll force cout to invoke method printing ints not chars - this will solve your issue.
..or more 'c++++ ish' ;-)
cout << static_cast(out);
..or this which for most looks weird:
cout << int(out);
Use int out instead of char out. cout prints char as a character not an integer. The ASCII values 0-15 are unprintable control characters.
the reason why u got an 'A' from print is that out is char ,and after 'A' - 'A' + 10, out is a character whose ascii value is 10 instead of integer 10. So u will get a character whose ascii value is 10 instead of getting 'A'.After checking the ascii table, that character is null,which can explain why u get nothing in the output.
Simply use std::stringstream for this purpose.
#include <iostream>
#include <sstream>
int main (int argc, char ** argv)
{
// use hex formatting
std::stringstream stream;
stream << std::hex << 'A';
// retrieve value of the hex input character
int value;
stream >> value;
std::cout << value << std::endl; // prints 10
// reset the stream
stream.str ();
stream.clear();
// also works for strings
stream << "0xABC" << std::endl;
stream >> value;
std::cout << value << std::endl; // prints 2748
return 0;
}

String after appending Char changning its size

I want to test what if string append char's size, and below is the outcome.
I know that the string end with the null character, but why the outcome is like that?
#include <iostream>
#include <string>
using namespace std;
int main(){
string a = "" + 'a'; //3
string b = "" + '1'; //2
string c = "a" + 'a'; //2
string d = "1" + '1'; //3
string e = "\0" + 'a'; //20
string f = "\0" + '1'; //1
string g = "a" + '\0'; //1
string h = "1" + '\0'; //1
string i = "" + '\0'; //0
string j = "" + '\0'; //0
cout << a.size() << endl;
cout << b.size() << endl;
cout << c.size() << endl;
cout << d.size() << endl;
cout << e.size() << endl;
cout << f.size() << endl;
cout << g.size() << endl;
cout << h.size() << endl;
cout << i.size() << endl;
cout << j.size() << endl;
return 0;
}
Your code is not doing what you think.
String literals decay to const char *, and char is an integer type. If you try to sum them, the compiler finds that the simplest way to make sense of that stuff is to convert chars to ints, so the result is performing pointer arithmetic over the string literals - e.g. ""+'a' goes to the 97th character in memory after the beginning of the string literal "" (if 'a' is represented by 97 on your platform).
This results in garbage being passed to the string constructor, which will store inside the string being constructed whatever it finds at these locations of memory until it founds a \0 terminator. Hence the "strange" results you get (which aren't reproducible, since the exact memory layout of the string table depends from the compiler).
Of course all this is undefined behavior as far as the standard is concerned (you are accessing char arrays outside their bounds, apart from the cases where you add \0).
To make your code do what you mean, at least one of the operands must be of type string:
string c = string("a") + 'a';
or
string c = "a" + string("a");
so the compiler will see the relevant overloads of operator+ that involve std::string.
Most of your initializers have undefined behaviour. Consider, for example:
string a = "" + 'a';
You are adding a char to a char pointer. This advances the pointer by the ASCII value of the char, and uses the resulting (undefined) C string to initialize a.
To fix, change the above to:
string a = string("") + 'a';