Converting char to unsigned integer - c++

I read a huge binary file into a vector of chars.
I need to treat every byte as an unsigned integer(from 0 to 255); and do some arithmetics. How can I convert vector to vector?
char a = 227;
cout << a;
prints ?
char a = 227;
int b = (int) a;
cout << b << endl;
prints -29
char a = 227;
unsigned int b = (unsigned int) a;
cout << b << endl;
prints 4294967267
char a = 227;
unsigned char b = (unsigned char) a;
cout << b << endl;
prints ?

std::vector<char> source;
// ... read values into source ...
// Make a copy of source with the chars converted to unsigned chars.
std::vector<unsigned char> destination;
for (const auto s : source) {
destination.push_back(static_cast<unsigned char>(s))
}
// Examine the values in the new vector. We cast them to int to get
// the output stream to format it as a number rather than a character.
for (const auto d : destination) {
std::cout << static_cast<int>(d) << std::endl;
}

Related

std::cout print char as 2-digit hex [duplicate]

#include <iostream>
using namespace std;
int main()
{
char c1 = 0xab;
signed char c2 = 0xcd;
unsigned char c3 = 0xef;
cout << hex;
cout << c1 << endl;
cout << c2 << endl;
cout << c3 << endl;
}
I expected the output are as follows:
ab
cd
ef
Yet, I got nothing.
I guess this is because cout always treats 'char', 'signed char', and 'unsigned char' as characters rather than 8-bit integers. However, 'char', 'signed char', and 'unsigned char' are all integral types.
So my question is: How to output a character as an integer through cout?
PS: static_cast(...) is ugly and needs more work to trim extra bits.
char a = 0xab;
cout << +a; // promotes a to a type printable as a number, regardless of type.
This works as long as the type provides a unary + operator with ordinary semantics. If you are defining a class that represents a number, to provide a unary + operator with canonical semantics, create an operator+() that simply returns *this either by value or by reference-to-const.
source: Parashift.com - How can I print a char as a number? How can I print a char* so the output shows the pointer's numeric value?
Cast them to an integer type, (and bitmask appropriately!) i.e.:
#include <iostream>
using namespace std;
int main()
{
char c1 = 0xab;
signed char c2 = 0xcd;
unsigned char c3 = 0xef;
cout << hex;
cout << (static_cast<int>(c1) & 0xFF) << endl;
cout << (static_cast<int>(c2) & 0xFF) << endl;
cout << (static_cast<unsigned int>(c3) & 0xFF) << endl;
}
Maybe this:
char c = 0xab;
std::cout << (int)c;
Hope it helps.
Another way is to overload the << operator:
#include <iostream>
using namespace std;
typedef basic_ostream<char, char_traits<char>> basicOstream;
/*inline*/ basicOstream &operator<<(basicOstream &stream, char c) {
return stream.operator<<(+c);
}
/*inline*/ basicOstream &operator<<(basicOstream &stream, signed char c) {
return stream.operator<<(+c);
}
/*inline*/ basicOstream &operator<<(basicOstream &stream, unsigned char c) {
return stream.operator<<(+c);
}
int main() {
char var1 = 10;
signed char var2 = 11;
unsigned char var3 = 12;
cout << var1 << endl;
cout << var2 << endl;
cout << var3 << endl;
return 0;
}
which prints the following output:
10
11
12
Process finished with exit code 0
I think it's very neat and useful. hope it hepls!
And Also if you want it to print a hex value you can do like this:
basicOstream &operator<<(basicOstream &stream, char c) {
return stream.operator<<(hex).operator<<(c);
} // and so on...
What about:
char c1 = 0xab;
std::cout << int{ c1 } << std::endl;
It's concise and safe, and produces the same machine code as other methods.
Another way to do it is with std::hex apart from casting (int):
std::cout << std::hex << (int)myVar << std::endl;
I hope it helps.

How to collect all the elements into one?

My code parses an integer into parts and writes them to an array, but now I want to collect the array back into an integer.
I will modify the data inside the array so I need to collect everything back after the changes.
int a = 123456789;
std::string stringInt = std::to_string(a);
std::vector<int> numbers;
numbers.reserve(stringInt.length());
for (const auto& chr : stringInt)
{
// ...
numbers.push_back(chr - '0');
cout << chr << "\n" << endl;
}
You can add up the integers, multiplying the result by 10 every time:
int b = 0;
for (const auto& chr : stringInt)
{
numbers.push_back(chr - '0');
b *= 10;
b += chr - '0';
}
std::cout << b << std::endl;
Alternatively you can put the chars into a string instead of turning them into int and putting them into a vector and then use std::stoi to get an int back out of the string:
std::string numbers;
for (const auto& chr : stringInt)
{
numbers.push_back(chr);
cout << chr << "\n" << endl;
}
int b = std::stoi(numbers);
std::cout << b << std::endl;

ifstream::read keeps returning incorrect values

I'm trying to read a .bin file and return the hexadecimal values. It all works fine until it has to read values like "F0" or "A0". It keeps returning "fffff0" or "ffffa0". When I modify the function to return decimal values the console shows "-16" and "-96" while all other correct returned values are positive.
void reader(string input) {
int size;
char *storage;
ifstream file(input, ios::in | ios::binary);
if (file.is_open()) {
file.seekg(0, ios::end);
size = file.tellg();
storage = new char[size];
file.seekg(0, ios::beg);
file.read(storage, size);
file.close();
for (int i = 0; i < size; i++)
{
cout << hex << (int)storage[i] << endl;
}
}
else {cout << "could not open file" << endl;}
}
"char" is a signed value. When the top bit of char is set it represents a negative value (e.g 0x80 to 0xFF). When you cast a negative value to a different size integer the value is preserved which results in a different value in hex.
#include <iostream>
int main()
{
char ch = 0xF0;
int value = ch;
std::cout << value << std::endl;
std::cout << std::hex << value << std::endl;
}
The above program prints "-16, fffffff0". The program is actually equivalent to:
#include <iostream>
int main()
{
char ch = -16;
int value = ch;
std::cout << value << std::endl;
std::cout << std::hex << value << std::endl;
}
To get your intended behaviour you need to mask the value:
#include <iostream>
int main()
{
char ch = 0xF0;
int value = ch & 0xFF;
std::cout << value << std::endl;
std::cout << std::hex << value << std::endl;
}

How to output a character as an integer through cout?

#include <iostream>
using namespace std;
int main()
{
char c1 = 0xab;
signed char c2 = 0xcd;
unsigned char c3 = 0xef;
cout << hex;
cout << c1 << endl;
cout << c2 << endl;
cout << c3 << endl;
}
I expected the output are as follows:
ab
cd
ef
Yet, I got nothing.
I guess this is because cout always treats 'char', 'signed char', and 'unsigned char' as characters rather than 8-bit integers. However, 'char', 'signed char', and 'unsigned char' are all integral types.
So my question is: How to output a character as an integer through cout?
PS: static_cast(...) is ugly and needs more work to trim extra bits.
char a = 0xab;
cout << +a; // promotes a to a type printable as a number, regardless of type.
This works as long as the type provides a unary + operator with ordinary semantics. If you are defining a class that represents a number, to provide a unary + operator with canonical semantics, create an operator+() that simply returns *this either by value or by reference-to-const.
source: Parashift.com - How can I print a char as a number? How can I print a char* so the output shows the pointer's numeric value?
Cast them to an integer type, (and bitmask appropriately!) i.e.:
#include <iostream>
using namespace std;
int main()
{
char c1 = 0xab;
signed char c2 = 0xcd;
unsigned char c3 = 0xef;
cout << hex;
cout << (static_cast<int>(c1) & 0xFF) << endl;
cout << (static_cast<int>(c2) & 0xFF) << endl;
cout << (static_cast<unsigned int>(c3) & 0xFF) << endl;
}
Maybe this:
char c = 0xab;
std::cout << (int)c;
Hope it helps.
Another way is to overload the << operator:
#include <iostream>
using namespace std;
typedef basic_ostream<char, char_traits<char>> basicOstream;
/*inline*/ basicOstream &operator<<(basicOstream &stream, char c) {
return stream.operator<<(+c);
}
/*inline*/ basicOstream &operator<<(basicOstream &stream, signed char c) {
return stream.operator<<(+c);
}
/*inline*/ basicOstream &operator<<(basicOstream &stream, unsigned char c) {
return stream.operator<<(+c);
}
int main() {
char var1 = 10;
signed char var2 = 11;
unsigned char var3 = 12;
cout << var1 << endl;
cout << var2 << endl;
cout << var3 << endl;
return 0;
}
which prints the following output:
10
11
12
Process finished with exit code 0
I think it's very neat and useful. hope it hepls!
And Also if you want it to print a hex value you can do like this:
basicOstream &operator<<(basicOstream &stream, char c) {
return stream.operator<<(hex).operator<<(c);
} // and so on...
What about:
char c1 = 0xab;
std::cout << int{ c1 } << std::endl;
It's concise and safe, and produces the same machine code as other methods.
Another way to do it is with std::hex apart from casting (int):
std::cout << std::hex << (int)myVar << std::endl;
I hope it helps.

strip characters from char array pass as pointer in C++

any suggestion on how to strip characters from char array pass as pointer in C++. i must use memcpy function to copy.
void foo(char *test)
{
char a[1] = {0};
char b[1] = {0};
char c[1]= {0};
memcpy(&a,&test[0],1);
memcpy(&b,&test[1],1);
memcpy(&c,&test[2],1);
cout << a <<endl;
cout << b <<endl;
cout << c <<endl;
}
int main()
{
char uibuffer[4] = "ABC";
foo(uibuffer);
return 0;
}
the current output is:
ABC��
BC��
C��
desired output is:
A
B
C
void foo(char *test)
{
/* Please note, you need to add one extra byte here for a terminator */
char a[2] = {0};
char b[2] = {0};
char c[2]= {0};
memcpy(&a,&test[0],1);
memcpy(&b,&test[1],1);
memcpy(&c,&test[2],1);
cout << a <<endl;
cout << b <<endl;
cout << c <<endl;
}
int main()
{
char uibuffer[4] = "ABC";
foo(uibuffer);
return 0;
}
OR
Think about improving your code by getting rid of arrays and memory copying. Simple char a = buffer[x] will do the trick.
since you haven't created \0 terminated strings do:
cout << a[0] <<endl;
cout << b[0] <<endl;
cout << c[0] <<endl;
Don't make a, b and c an array. Probably won't compile but to illustrate.
void foo(char *test)
{
char a = 0;
char b = 0;
char c = 0;
memcpy(&a,&test[0],1);
memcpy(&b,&test[1],1);
memcpy(&c,&test[2],1);
cout << a <<endl;
cout << b <<endl;
cout << c <<endl;
}
int main()
{
char uibuffer[4] = "ABC";
foo(uibuffer);
return 0;
}
Don't make them arrays:
char a = test[0];
char b = test[1];
char c = test[2];
You can still use memcpy, if you must, just as you are now.