How to print UTF-8 symbols by entering decimal number? - c++

For example I enter decimal number 210 that is symbol "Ò".
For example code
int a = 210;
wcout << wchar_t (a);
works fine, but before "wcout" I use "cout" and they are not compatible.
int main() {
string a = "\u";
string b = "210";
string c = a + b;
cout << b + a << endl;
cout << "Second cout message...";
}
ERROR:
main.cpp:4:15: error: \u used with no
following hex digits
string a = "\u";
^~
1 error generated.
compiler exit status 1

You can use std::wcrtomb to convert wide character to multi byte string. See https://en.cppreference.com/w/cpp/string/multibyte/wcrtomb
#include <iostream>
#include <cwchar>
#include <clocale>
int main() {
std::setlocale(LC_ALL, "en_US.utf8");
wchar_t wc = 127820;
char mbstr[5]{};
std::mbstate_t state{};
std::wcrtomb(mbstr, wc, &state);
std::cout << mbstr << std::endl;
}
https://ideone.com/QVMppe
Also if you are interested in what Unicode is and how it is encoded with variable width character encoding, see https://en.wikipedia.org/wiki/UTF-8

UTF-8 is very easy to encode manually, eg:
std::string toUTF8(uint32_t cp)
{
char utf8[4];
int len = 0;
if (cp <= 0x007F)
{
utf8[0] = static_cast<char>(cp);
len = 1;
}
else
{
if (cp <= 0x07FF)
{
utf8[0] = 0xC0;
len = 2;
}
else if (cp <= 0xFFFF)
{
utf8[0] = 0xE0;
len = 3;
}
else if (cp <= 0x10FFFF)
{
utf8[0] = 0xF0;
len = 4;
}
else
throw std::invalid_argument("invalid codepoint");
for(int i = 1; i < len; ++i)
{
utf8[len-i] = static_cast<char>(0x80 | (cp & 0x3F));
cp >>= 6;
}
utf8[0] |= static_cast<char>(cp);
}
return std::string(utf8, len);
}
int main()
{
std::string utf8 = toUTF8(210);
std::cout << utf8;
}
Live Demo
Make sure your console actually supports displaying UTF-8 text.

Related

How encrypt a string with XOR without include strange characters?

The following code works fine, but i want that not include strange characters on encrypted string, like '\x03' for example. How to achieve this?
string XOR_Encryption(string toBeEncrypted, string sKey)
{
string sEncrypted(toBeEncrypted);
unsigned int iKey(sKey.length()), iIn(toBeEncrypted.length()), x(0);
for (unsigned int i = 0; i < iIn; i++)
{
sEncrypted[i] = toBeEncrypted[i] ^ sKey[x];
if (++x == iKey) { x = 0; }
}
return sEncrypted;
}
Usage:
string message = "gbpi";
string Key("Q4s4R4t");
string encrypted_message = XOR_Encryption(message, Key);
cout << "encoded: " << encrypted_message << endl;
string decryptedMessage = XOR_Encryption(encrypted_message, Key);
cout << "decoded: " << decryptedMessage << endl;
With reference to suggestion of #kelalaka, here is a solution using Hex encode:
#include "stdafx.h"
#include <stdio.h>
#include <conio.h>
#include <string>
#include <stdlib.h>
#include <iostream>
string XOR_Encryption(string toBeEncrypted, string sKey)
{
string sEncrypted(toBeEncrypted);
unsigned int iKey(sKey.length()), iIn(toBeEncrypted.length()), x(0);
for (unsigned int i = 0; i < iIn; i++)
{
sEncrypted[i] = toBeEncrypted[i] ^ sKey[x];
if (++x == iKey) { x = 0; }
}
return sEncrypted;
}
void stream2hex(const string str, string& hexstr, bool capital = false)
{
hexstr.resize(str.size() * 2);
const size_t a = capital ? 'A' - 1 : 'a' - 1;
for (size_t i = 0, c = str[0] & 0xFF; i < hexstr.size(); c = str[i / 2] & 0xFF)
{
hexstr[i++] = c > 0x9F ? (c / 16 - 9) | a : c / 16 | '0';
hexstr[i++] = (c & 0xF) > 9 ? (c % 16 - 9) | a : c % 16 | '0';
}
}
void hex2stream(const string hexstr, string& str)
{
str.resize((hexstr.size() + 1) / 2);
for (size_t i = 0, j = 0; i < str.size(); i++, j++)
{
str[i] = (hexstr[j] & '#' ? hexstr[j] + 9 : hexstr[j]) << 4, j++;
str[i] |= (hexstr[j] & '#' ? hexstr[j] + 9 : hexstr[j]) & 0xF;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
string text = "text";
string Key("password");
string encrypted_message = XOR_Encryption(text, Key);
stream2hex(encrypted_message, encrypted_message, true);
cout << "encoded: " << encrypted_message << endl;
hex2stream(encrypted_message, encrypted_message);
string decryptedMessage = XOR_Encryption(encrypted_message, Key);
cout << "decoded: " << decryptedMessage << endl;
getch();
return 0;
}

Splitting char array

I have a char **names array that basically stores names from a file.
This is my .txt file
Mike, Sam, Stuart
Andre, Williams, Phillips
Patels, Khan, Smith
Basically, I want to split and store the names before the , character.
For example, Mike, Sam, Stuart will become...
newName[0] = Mike
newName[1] = Sam
newName[2] = Stuart
I have something like this...
for (int i=0; i<3; i++)
{
for (int j=60, j>0; j--)
{
if(names[i][j] == ',')
{
cout << j << endl; //THIS PRINTS OUT THE POSITION. HOW CAN I STORE THE POSITION AND DO SOMETHING?
}
}
}
I would appreciate it if someone could help me with my code, it is in the right direction. I don't want to use any vectors classes
I have attempted to store marks of these students, however I want to add it to a double *marks[2] array.
This is my .txt file...
69.9, 56.5
29.8, 20.0
35.6, 45.0
This is my code...
char **values;
char * pch;
pch = strtok (values[i], " ,");
while (pch != NULL)
{
sscanf(pch, "%f, %f", &marks[i][0], &marks[i][1]);
pch = strtok (NULL, " ,");
}
I am getting random values such as 1.28277e-307 and 1.96471e+257
look up the strtok command it will be very helpful to you.
This code looks for hyphen characters and prints stuff... change it to commas
#include <string.h>
#include <stdio.h>
int main()
{
const char str[80] = "This is - www.tutorialspoint.com - website";
const char s[2] = "-";
char * newName[100]; /* at most 100 names */
int iCurName = 0;
char *token;
/* get the first token */
token = strtok(str, s);
/* walk through other tokens */
while( token != NULL )
{
printf( " %s\n", token );
newName[iCurName] = malloc (char *) (strlen(token) + 1);
strcpy(newName[iCurName],token);
iCurrName ++;
token = strtok(NULL, s);
}
return(0);
}
Use function strtok() to split input line into tokens; use strcpy_s() to copy each token into name buffer.
Note 1: The strtok() function replaces each separator with '\0' character, so the line variable cannot be declared with const. If your input buffer must be constant, for example if you want to use the whole line for something else, make a copy of it before calling strtok() function.
Note 2: You might want to trim space in addition to splitting your input line.
#define MAX_LINE_LENGTH 80
#define MAX_NAME_LENGTH 20
#define MAX_NAMES_PER_LINE 3
const char constInput = "Mike, Sam, Stewart";
char line[MAX_LINE_LENGTH];
strcpy_s(line, MAX_LINE_LENGTH, constInput);
char *separator = ",";
char newName[MAX_NAMES_PER_LINE][MAX_NAME_LENGTH];
int i = 0;
char *token = strtok(line, separator);
while ((i < MAX_NAMES_PER_LINE) && ((token = strtok(NULL, separator)) != NULL))
{
strcpy_s(newName[i++], MAX_NAME_LENGTH, token);
}
char newName[3][60];
for (int i=0; i<3; i++){
int r=0, c=0;
for (int j=0; j<60; j++){
if(names[i][j] == ',' || names[i][j] == '\0'){
newName[r++][c] = '\0';
c = 0;
if(names[i][j] == '\0'){
cout << newName[0] << '\n'
<< newName[1] << '\n'
<< newName[2] << '\n' << endl;
break;
}
while(names[i][++j] == ' ')
;
--j;
} else {
newName[r][c++] = names[i][j];
}
}
}
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ifstream inf("data.txt");
double marks[2];
char ch;
while(inf.good()){
inf >> marks[0] >> ch >> marks[1];
cout << "mark1:" << marks[0] << endl;
cout << "mark2:" << marks[1] << endl;
}
}
I don't know if this function works fast enough, but here it is:
char** split_quotes(char *input, char separator = ' ', bool keep_quotes = false)
{
if (&input && input)
{
size_t length = strlen(input);
char **chunks = new char*[length];
bool inQuotes = false;
size_t count = 0, from = 0;
for (size_t i = 0; i < length; i++)
{
if (input[i] == '"')
{
inQuotes = !inQuotes;
}
else if (input[i] == separator && !inQuotes)
{
size_t strlen = i - from;
if (strlen > 0)
{
if (!keep_quotes && input[from] == '"' && input[i - 1] == '"')
{
from++; strlen -= 2;
}
chunks[count] = new char[strlen + 1]();
strncpy(chunks[count], &input[from], strlen);
count++;
}
from = i + 1;
}
}
if (from < length)
{
size_t strlen = length - from;
if (!keep_quotes && input[from] == L'"' && input[length - 1] == L'"')
{
from++; strlen -= 2;
}
chunks[count] = new char[strlen + 1]();
strncpy(chunks[count], &input[from], strlen);
count++;
}
// Save chunks to result array //
char **result = new char*[count + 1]();
memcpy(result, chunks, sizeof(char*) * count);
// free chunks //
delete[] chunks;
return result;
}
return NULL;
}
Usage:
wchar_t **name = split_quotes(L"Mike,Donald,\"My Angel\",Anna", L',');
if (name)
{
while (*name++)
{
std::wcout << "Person: " << *name << std::endl;
}
}

Converting binary to ASCII

I have a text full of binary values(0-1) and i'm trying to convert it to ASCII , I made a code but it didn't work well and it takes too long time and writing, this is a part of it:
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main()
{
ofstream fout("C:\\test.txt",ios :: binary);
ifstream file("E:\\mnmn.txt");
string content;
while(file >> content)
{
for (size_t i = 0; i < content.size(); i++)
{
while((content[i] == '0')
&& (content[i+1] == '0')
&& (content[i+2] == '0')
&& (content[i+3] == '0')
&& (content[i+4] == '0')
&& (content[i+5] == '0')
&& (content[i+6] == '0')
&& (content[i+7] == '0')
{
char *data = "00000000";
char c = strtol(data, 0, 2);
fout<<c;
}
}
}
}
i have to do the same for all values and even if i did the program repeats the values because the zeros and ones is connected without any spaces between , isn't there a better way to convert it?
the text contains:
00001111101010001001010101110
etc..
GCC 4.8.2: g++ -Wall -Wextra -std=c++11 read-01.cpp
#include <bitset>
#include <fstream>
int main() {
std::ofstream fout("test.txt");
std::ifstream fin("mnmn.txt");
char ic;
std::bitset<8> oc;
int i = 8;
while (fin >> ic) {
oc[--i] = ic - '0';
if (0 == i) {
fout << static_cast<char>(oc.to_ulong());
i = 8; } }
return 0; }
You can read the contents of the file character by character and accumulate the characters in a variable. After reading 8 characters, you have the ASCII value. The core of your function can be changed to:
int inChar = 0;
int outChar = 0;
int count = 0;;
while( (inChar = file.get()) != EOF )
{
int x = inChar - '0';
// Ignore newlines and other characters that are not '0' or '1'.
if ( x == 0 || x == 1 )
{
// Accumulate the bit into the output char.
outChar = (outChar << 1) + x;
++count;
if ( count == 8 )
{
fout.put(outChar);
outChar = 0;
count = 0;
}
}
}
// Deal with unused outChar.
if ( count > 0 )
{
cout << "There are " << count << " bits that were not used.\n";
}
If you want to get eight characters (bits) at a time from the input you read, then you should use the std::string::substr function, and you can use the resulting string directly, either in std::stoi (or if you don't have it std::strtol).
Something like
while (file >> content)
{
do
{
std::string byte = content.substr(0, 8); // Get eight "bits"
fout << std::stoi(byte, nullptr, 2); // Convert and output to file
content = content.substr(8); // The remaining bits
} while (!content.empty());
}

Missing punctuation from C++ hex2bin

While trying to duplicate PHP's bin2hex($s) and pack('H*',$s) (aka hex2bin($s) in PHP 5.4.3+) in GCC/Linux C++, I seem to have it figured out except that it's dropping punctuation for some strange reason. Can you figure out what I might be doing wrong in the hex2bin() function? I compared PHP's bin2hex() with mine and it appears to be working there properly, so the problem is in hex2bin().
#include <strings.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
string bin2hex(string s) {
int nLen = s.length();
string sOut;
char cBuff[2];
for (int i = 0; i < nLen; i++) {
sprintf(cBuff,"%.2x",s[i]);
sOut.append(cBuff);
cBuff[0] = '\0';
}
return sOut;
}
string hex2bin(string s) {
int nLen = s.length();
string sOut;
char cBuff1[2];
char cBuff2[2];
char cBuff[1];
int n,n1,n2;
for (int i = 0; i <= nLen; i+=2) {
sprintf(cBuff1,"%c",s[i]);
sprintf(cBuff2,"%c",s[i+1]);
n1 = atoi(cBuff1);
n2 = atoi(cBuff2);
n = (n1 * 16) + n2;
sprintf(cBuff,"%c",n);
sOut.append(cBuff);
cBuff[0] = '\0';
cBuff1[0] = '\0';
cBuff2[0] = '\0';
}
return sOut;
}
int main() {
string s;
string sResult;
s = "This is a 123 test.";
sResult = bin2hex(s);
printf("ENCODED: %s\n",sResult.c_str());
sResult = hex2bin(sResult);
printf("UNENCODED: %s\n",sResult.c_str());
return 1;
}
This emits:
ENCODED: 5468697320697320612031323320746573742e
UNENCODED: This is a 123 test
Okay, sleeves rolled up: let's look at C++ version:
Live on Coliru
Don't use C strings unless you need to (sprintf to build a two-char string is not... very efficient)
Use iostreams to encode/decode the hex digits (std::hex)
The hex2bin could optimized, but I went for "simpler"
I added a modicum of input sanitizing on hex2bin
#include <string>
#include <sstream>
#include <iomanip>
std::string bin2hex(std::string const &s) {
std::ostringstream oss;
for (unsigned char ch : s)
oss << std::hex << std::setw(2) << std::setfill('0') << (int) ch;
return oss.str();
}
#include <cassert>
std::string hex2bin(std::string const& s) {
assert(s.length() % 2 == 0);
std::string sOut;
sOut.reserve(s.length()/2);
std::string extract;
for (std::string::const_iterator pos = s.begin(); pos<s.end(); pos += 2)
{
extract.assign(pos, pos+2);
sOut.push_back(std::stoi(extract, nullptr, 16));
}
return sOut;
}
#include <iostream>
int main() {
std::cout << "ENCODED: " << bin2hex("This is a 123 test.") << "\n";
std::cout << "DECODED: " << hex2bin(bin2hex("This is a 123 test.")) << "\n";
}
Output:
ENCODED: 5468697320697320612031323320746573742e
DECODED: This is a 123 test.
With all but the period '.' you just went lucky: the hex digits didn't use an actual hexadecimal value. However, for the period you got 2e but you tried to decode the e using atoi("e"), roughly: that won't work as atoi() requires a decimal value. You could use strtol(str, 0, 16) instead to decode the hexadecimal value.
Note that you have a few buffer overruns when you are using sprintf(): this function writes a terminating null character. In general, you are much better off to snprintf() to avoid buffer overruns. Also, in your decoding routine you access values beyond the end of your string (you use i <= nLen with nLen = s.length() and then access s[i] and s[i+1]). Of course, the code is far too complex:
#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>
std::string bin2hex(std::string s) {
std::ostringstream out;
out << std::hex << std::setfill('0');
for (char c: s) {
out << std::setw(2) << int(c);
}
return out.str();
}
std::string hex2bin(std::string s) {
std::string rc;
int nLen = s.length();
int tmp;
for (int i(0); i + 1 < nLen; i += 2) {
if (std::istringstream(s.substr(i, 2)) >> std::hex >> tmp) {
rc.push_back(tmp);
}
}
return rc;
}
int main() {
std::string s;
std::string sResult;
s = "This is a 123 test.";
sResult = bin2hex(s);
std::cout << "ENCRYPTED: " << sResult << '\n';
sResult = hex2bin(sResult);
std::cout << "UNENCRYPTED: " << sResult << '\n';
return 1;
}
Your code does not convert hexadecimal digits correctly because atoi can only handle decimal digits. Try this
sprintf(cBuff1,"%c",s[i]);
sprintf(cBuff2,"%c",s[i+1]);
n1 = strtoul(cBuff1, 0, 16);
n2 = strtoul(cBuff2, 0, 16);
Also your for loop should be
for (int i = 0; i < nLen; i+=2) {
n1 = atoi(cBuff1);
n2 = atoi(cBuff2);
n = (n1 * 16) + n2;
if cbuff1 is, say, "a", then this won't work, since a is not a digit. It works fine for digits that are '0-9', but not 'a-f'.
You will need to translate non-digits to numeric values.
There are quite a few ways to convert a hex value string to a byte. I think this is pretty decent:
int hexchar(char c)
{
if (c >= '0' && c <= '9') return c - '0';
// if you need to support upper-case hex:
// c = tolower(c);
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
// If we get here, panic
cout << "Error, invalid hex digit:" << c << endl;
return -1;
}
int hexbyte(string s)
{
for(i = 0; i < s.length(); i+=2)
{
char c = hexbyte(s[i]);
c <<= 4;
c += hexbyte(s[i+1];
cout << c;
}
}
Try these trivial routines, good for C and C ++
/*------------------------------------------+
| bin2hex bin2hex bin2hex |
+------------------------------------------*/
static char *bin2hex(unsigned char *s, long L)
{
static char hex[2048];
long i,l=0;
for (i=0; i<L; i++) l+=sprintf(&hex[l], "%02x", 0xFF & (*(s+i)));
hex[l]=0;
return hex;
}
/*------------------------------------------+
| hex2bin hex2bin hex2bin |
+------------------------------------------*/
static char *hex2bin( char *s)
{
static char bin[2048];
unsigned int i,e,l=0,L=strlen(s);
for (i=0; i<L; i+=2) { sscanf(s+i, "%02x",&e); bin[l++]=(char)e; }
bin[l]=0;
return bin;
}

Converting string of 1s and 0s into binary value

I'm trying to convert an incoming sting of 1s and 0s from stdin into their respective binary values (where a string such as "11110111" would be converted to 0xF7). This seems pretty trivial but I don't want to reinvent the wheel so I'm wondering if there's anything in the C/C++ standard libs that can already perform such an operation?
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char * ptr;
long parsed = strtol("11110111", & ptr, 2);
printf("%lX\n", parsed);
return EXIT_SUCCESS;
}
For larger numbers, there as a long long version, strtoll.
You can use std::bitset (if then length of your bits is known at compile time)
Though with some program you could break it up into chunks and combine.
#include <bitset>
#include <iostream>
int main()
{
std::bitset<5> x(std::string("01011"));
std::cout << x << ":" << x.to_ulong() << std::endl;
}
You can use strtol
char string[] = "1101110100110100100000";
char * end;
long int value = strtol (string,&end,2);
You can use Boost Dynamic Bitset:
boost::dynamic_bitset<> x(std::string("01011"));
std::cout << x << ":" << x.to_ulong() << std::endl;
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
string getBinaryString(int value, unsigned int length, bool reverse) {
string output = string(length, '0');
if (!reverse) {
for (unsigned int i = 0; i < length; i++) {
if ((value & (1 << i)) != 0) {
output[i] = '1';
}
}
}
else {
for (unsigned int i = 0; i < length; i++) {
if ((value & (1 << (length - i - 1))) != 0) {
output[i] = '1';
}
}
}
return output;
}
unsigned long getInteger(const string& input, size_t lsbindex, size_t msbindex) {
unsigned long val = 0;
unsigned int offset = 0;
if (lsbindex > msbindex) {
size_t length = lsbindex - msbindex;
for (size_t i = msbindex; i <= lsbindex; i++, offset++) {
if (input[i] == '1') {
val |= (1 << (length - offset));
}
}
}
else { //lsbindex < msbindex
for (size_t i = lsbindex; i <= msbindex; i++, offset++) {
if (input[i] == '1') {
val |= (1 << offset);
}
}
}
return val;
}
int main() {
int value = 23;
cout << value << ": " << getBinaryString(value, 5, false) << endl;
string str = "01011";
cout << str << ": " << getInteger(str, 1, 3) << endl;
}