I have Hexadecimal format IP4 address which needs to be converted to string. Could you please let me know what needs to be changed in the below code to get the right answer. Thanks a lot for the support.
int main (void) {
char buff[16];
string IpAddressOct = "EFBFC845";
string xyz="0x"+IpAddressOct+"U";
unsigned int iStart=atoi(xyz.c_str());
sprintf (buff, "%d.%d.%d.%d", iStart >> 24, (iStart >> 16) & 0xff,(iStart >> 8) & 0xff, iStart & 0xff);
printf ("%s\n", buff);
return 0;
}
The output I am getting is 0.0.0.0, but expected output is 239.191.200.69
atoi() only takes integers. If you call atoi("1"), it will return 1. If you call atoi("a"), it will return 0.
What you should do is create a mapping between hex values and do the calculation every two character. The following is an example:
1 #include <map>
2 #include <iostream>
3 #include <cstring>
4 #include <string>
5 #include <vector>
6
7 using namespace std;
8
9 static std::map<unsigned char, int> hexmap;
10
11 void init() {
12 hexmap['0'] = 0;
13 hexmap['1'] = 1;
14 hexmap['2'] = 2;
15 hexmap['3'] = 3;
16 hexmap['4'] = 4;
17 hexmap['5'] = 5;
18 hexmap['6'] = 6;
19 hexmap['7'] = 7;
20 hexmap['8'] = 8;
21 hexmap['9'] = 9;
22 hexmap['a'] = 10;
23 hexmap['A'] = 10;
24 hexmap['b'] = 11;
25 hexmap['B'] = 11;
26 hexmap['c'] = 12;
27 hexmap['C'] = 12;
28 hexmap['d'] = 13;
29 hexmap['D'] = 13;
30 hexmap['e'] = 14;
31 hexmap['E'] = 14;
32 hexmap['f'] = 15;
33 hexmap['F'] = 15;
34 }
35
36 vector<int> parseIp(string income) {
37 vector<int> ret;
38 if (income.size() > 8)
39 // if incoming string out of range
40 return ret;
41 int part = 0;
42 char buf[4];
43 for (int i = 0; i < income.size(); ++i) {
44 part += hexmap[income[i]];
45 cout << income[i] << " " << hexmap[income[i]] << " " << part << endl;
46 if ((i % 2) == 1) {
47 ret.push_back(part);
48 part = 0;
49 } else {
50 part *= 16;
51 }
52 }
53
54 return ret;
55 }
56
57 int main(void) {
58 init();
59 string ipAddressOct = "EFBFC845";
60 vector<int> ip = parseIp(ipAddressOct);
61 cout << ip[0] << "." << ip[1] << "." << ip[2] << "." << ip[3] << endl;
62 }
The above could be overly complicated. It is intended for example only.
Related
I have a string declared like so.
CHAR bkp[40] = "dc74699a8381da395f10b"; <- this value comes from querying a registry value
In memory (using VS memory window) I see..
0x00000071432FF918 64 63 37 34 36 39 39 61 38 33 38 31 64 61 33 39 35 66 31 30 62 00 .. .. .. ..
I am trying to convert the string to memory so that when I examine that memory address I see..
0x00000071432FF918 dc 74 69 9a 83 81 da 39 5f 10 0b .. .. .. ..
My project is in C++ but the function requires that it gets returned to a char *. So if the char array needs to be converted to a C++ string it can.
Simply iterate through the string, and for every 2-char pair, you can do some very simple calculations and bit shifts to extract the byte values. For example:
BYTE decodeHex(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
else if (c >= 'A' && c <= 'F')
return (c - 'A') + 10;
else if (c >= 'a' && c <= 'f')
return (c - 'a') + 10;
else
// illegal! throw something...
}
CHAR bkp[] = "dc74699a8381da395f100b";
int slen = strlen(bkp);
BYTE *bytes = new BYTE[slen / 2];
int blen = 0;
for(int i = 0; i < slen; i += 2)
{
bytes[blen++] = (decodeHex(bkp[i]) << 4) | decodeHex(bkp[i+1]);
}
// use bytes up to blen as needed...
delete[] bytes;
You need to convert you character array to a binary. Your input array is a hex string so this is rather straigforward.
unsigned char toBinary(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
return (c - 'a') + 10;
}
CHAR bkp[40] = "dc74699a8381da395f10b"
unsigned char b[20];
int bi = 0;
for(int i = 0; i < 40; i += 2)
{
char c = bkp[i];
unsigned char v = toBinary(bkp[i]) << 4;
v += toBinary(bkp[i+1])
b[bi++] = v;
}
The array is a character string, so you'll have to convert from characters to hex.
Let's use the old fashioned method:
const unsigned int length = sizeof(bkp);
const std::string hex_digits = "0123456789abcdef";
std::vector<uint8_t> destination;
for (unsigned int index = 0U; index < length; index += 2U)
{
uint8_t byte_value = 0;
std::string::size_type position = hex_digits.find(bkp[index]);
if (position == std::string::npos)
{
std::cerr << "invalid hex value at position " << index << "\n";
break;
}
byte_value = position;
++index;
position = hex_digits.find(bkp[index]);
if (position == std::string::npos)
{
std::cerr << "invalid hex value at position " << index << "\n";
break;
}
byte_value = (byte_value * 256) + position;
destination.push_back(byte_value);
}
Note: the above code uses C++ features since the original post was tagged as C++.
Just for some fun, you can perform the conversion using non-conditional operations.
In general:
'A' = 64, 'a' = 96, both of which have bit 6 set (value 64 decimal)
'0' = 48, so does not have the 6th bit set.
You can take the input, take the lower 4 bits to give us the 0->9, A->F or a->f and then take bit 6 and use it as a multiplier to add the +10 if needed.
#include <conio.h>
#include <stdio.h>
#include <string.h>
void HexStrToRaw(char* in, unsigned char* out)
{
for (int loop = 0, o_loop = 0; loop < strlen(in); loop += 2, o_loop++)
{
out[o_loop] = (((in[loop] & 15) + ((in[loop] >> 6) * 9)) << 4) | ((in[loop + 1] & 15) + ((in[loop + 1] >> 6) * 9));
}
}
int main(int argc, char** argv)
{
char in[40] = "dc74699a8381da395f10b";
unsigned char out[20];
HexStrToRaw(in, out);
for (int loop = 0; loop < sizeof(out); loop++)
{
printf("%d -> 0x%02x\n", loop, out[loop]);
}
return 0;
}
The output becomes:
0 -> 0xdc
1 -> 0x74
2 -> 0x69
3 -> 0x9a
4 -> 0x83
5 -> 0x81
6 -> 0xda
7 -> 0x39
8 -> 0x5f
9 -> 0x10
10 -> 0xb0
11 -> 0xcc
12 -> 0xcc
13 -> 0xcc
14 -> 0xcc
15 -> 0xcc
16 -> 0xcc
17 -> 0xcc
18 -> 0xcc
19 -> 0xcc
I was solving leetcode problem (Pairs of Songs With Total Durations Divisible by 60) and my solution below uses a map, when I change it to an unordered_map and print the elements inside the loop; the number of elements are much more than the input
class Solution {
public:
int numPairsDivisibleBy60(vector<int>& time) {
map<int, int> mod_d;
for(auto el : time) {
if(mod_d.count(el % 60) == 0) {
mod_d[el % 60] = 1;
}else mod_d[el % 60]++;
}
int ans = 0, i = 1;
//cout << "Size: " << mod_d.size() << "\n";
for(auto el : mod_d) {
int f = el.first, s = el.second;
cout << f << " " << 60 - f << "\n";
ans += mod_d[(60 - f) % 60] * (((60 - f) % 60) == f ? s - 1 : s);
}
return ans / 2;
}
};
Sample Input Test: [15, 63, 451, 213, 37, 209, 343, 319]
And the output is as follows:
3 57
15 45
19 41
29 31
31 29
33 27
37 23
41 19
43 17
45 15
57 3
The number of elements printed should be only 8 inside the loop, but with an unordered_map, the elements are much more.
The code that is not working well is below:
class Solution {
public:
int numPairsDivisibleBy60(vector<int>& time) {
unordered_map<int, int> mod_d;
for(auto el : time) {
if(mod_d.count(el % 60) == 0) {
mod_d[el % 60] = 1;
}else mod_d[el % 60]++;
}
int ans = 0, i = 1;
//cout << "Size: " << mod_d.size() << "\n";
for(auto el : mod_d) {
int f = el.first, s = el.second;
cout << f << " " << 60 - f << "\n";
ans += mod_d[(60 - f) % 60] * (((60 - f) % 60) == f ? s - 1 : s);
}
return ans / 2;
}
};
The only difference is the usage of unordered_map instead of a map
And it prints the elements wrongly as:
19 41
43 17
37 23
33 27
31 29
29 31
3 57
41 19
15 45
41 19
3 57
29 31
31 29
57 3
33 27
37 23
43 17
17 43
19 41
23 37
27 33
Anyone knows why is this odd behavior happening?
Alright I now understand, thank you so much all for the help. As per this link that shows the different ways to access a map, I see that using [] operator creates the elements if they are not there in the map and that is my mistake. When I should use std::map::at to retrieve map element
Fix
Checking if the element exist at first and using at() to access it
class Solution {
public:
int numPairsDivisibleBy60(vector<int>& time) {
unordered_map<int, int> mod_d;
for(auto el : time) {
if(mod_d.count(el % 60) == 0) {
mod_d[el % 60] = 1;
}else mod_d[el % 60]++;
}
int ans = 0, i = 1;
cout << "Size: " << mod_d.size() << "\n";
for(auto el : mod_d) {
int f = el.first, s = el.second;
cout << f << " " << i++ << "\n";
if(mod_d.count((60 - f) % 60) > 0) ans += mod_d.at((60 - f) % 60) * (((60 - f) % 60) == f ? s - 1 : s);
}
return ans / 2;
}
};
I am trying to write code that will list and reverse all digit pairs from 01 - 99. 01-09 is easy enough since you just have to multiply it by 10. I also know at least one way to reverse a given digit, I just don't know how to properly use it with a for loop.
This is what I have so far.
for ( int num99 =1 ; num99 > 0 && num99 < 100; num99 = num99+1)
{
if (num99 <10){
temp99 = num99 * 10;
cout << temp99 << endl;
}
else {
while (num99 != 0) {
remainder99 = num99 % 10;
reverse99 = (reverse99 * 10) + remainder99;
num99 = num99 / 10;
}
cout << reverse99 << endl;
}
}
Thank you for any help.
You have to reinitialize the values of remainder99, reverse99, temp99, num99 after you have used them.
You also have to prepend 0 to the result, when you reverse 10, 20, 30 etc... to get 01, 02, 03 etc...
After making the necessary changes, your program will look like this.
#include<iostream>
using namespace std;
int main(void)
{
int remainder99 = 0;
int reverse99 = 0;
int temp99 = 0;
for ( int num99 =1 ; num99 > 0 && num99 < 100; num99 = num99+1)
{
if (num99 <10){
temp99 = num99 * 10;
cout << temp99 << endl;
}
else {
temp99 = num99;
while (num99 != 0) {
remainder99 = num99 % 10;
reverse99 = (reverse99 * 10) + remainder99;
num99 = num99 / 10;
}
if(reverse99 < 10) cout << 0;
cout << reverse99 << endl;
reverse99 = 0;
remainder99 = 0;
num99 = temp99;
}
}
return 0;
}
Output is:
10
20
30
40
50
60
70
80
90
01
11
21
31
41
51
61
71
81
91
02
12
22
32
42
52
62
72
82
92
03
13
23
33
43
53
63
73
83
93
04
14
24
34
44
54
64
74
84
94
05
15
25
35
45
55
65
75
85
95
06
16
26
36
46
56
66
76
86
96
07
17
27
37
47
57
67
77
87
97
08
18
28
38
48
58
68
78
88
98
09
19
29
39
49
59
69
79
89
99
What you are trying to do is trying to operate over the loop variable, which causes unexpected results. Instead, separate your loop variable and your num99 variable like this:
for (int i = 1; i < 100; i++) {
int num99 = i;
if (num99 < 10) {
temp99 = num99 * 10;
cout << temp99 << endl;
} else {
remainder99 = num99 % 10;
num99 = num99 / 10;
if (remainder99 == 0) {
cout<<"0"<<num99<<endl;
} else {
reverse99 = remainder99 * 10 + num99;
cout << reverse99 << endl;
}
}
}
I have also taken the liberty of assuming that when you reverse the two digit numbers like 10, 20, etc, you want the output to be 01, 02, like that, if that is not what is expected by you, you can remove the if condition.
There are lot of issues with mentioned code like
Here reverse99 * 10 what is initial value of reverse99 ? Assign it as 0.
Here num99 = num99 / 10; you are modifying original num99 which outer loop variable, instead of this assign num99 to some temporary variable & do operation with that temporary variable.
Sample Code
int main(void) {
int temp99 = 0,remainder99 = 0, reverse99 = 0/* must initialize with 0 */ ;
for ( int num99 =1 ; num99 > 0 && num99 < 100; num99 += 1) {
if (num99 <10){
temp99 = num99 * 10;
std::cout << num99 << std::endl;
}
else {
reverse99 = 0;/*make it as 0 again for every iteration */
temp99 = num99; /* assign loop variable to temp99 & do the operation with that */
while (temp99 != 0) {
remainder99 = temp99 % 10;
reverse99 = (reverse99 * 10) + remainder99;
temp99 /= 10;
}
std::cout << reverse99 << std::endl;
}
}
return 0;
}
A C++11 oriented solution:
#include <vector>
#include <iostream>
#include <numeric>
#include <algorithm>
int main()
{
std::vector<int> in(99);
std::iota(in.begin(), in.end(), 1);
std::for_each(in.begin(), in.end(), [](int& i)
{
i = (i % 10)*10 + (i / 10);
}
);
for (const auto& val : in)
{
std::string out = std::to_string(in);
if (out.size() == 1)
{
out = '0' + out;
}
std::cout << out << std::endl;
}
return 0;
}
I want to fill a 8 x 8 matrix with values in a special order (see example below), but I don´t know how to do that. Each numer stands for the ordering number: For example: #3 in the matrix is the third value of a e.g. a measurment I want to add.
The Order should be:
1 2 5 6 17 18 21 22
3 4 7 8 19 20 23 24
9 10 13 14 25 26 29 30
11 12 15 16 27 28 31 32
33 34 37 38 49 50 53 54
35 36 39 40 51 52 55 56
41 42 45 46 57 58 61 62
43 44 47 48 59 60 63 64
Does anybody knows an algorithmus to do that?
I have tried this, but that´s not a good way to to it, and it´s not working for the whole matrix
int b= 0, ii = 0, a = 0, iii = 0
i are different measurement values
and now a for loop
if (ii == 1)
{
b++;
}
if (ii == 2)
{
a++, b--;
}
if (ii == 3)
{
b ++;
}
tempMatrix[a][b] = i;
cout << "TempMatrix " << tempMatrix[a][b] << " a " << a << " b " << b << endl;
if (ii == 3)
{
ii = -1;
a --;
b ++;
}
if (iii == 7)
{
a = a + 2;
b = 0;
iii = -1;
}
Use recursion:
#include <iostream>
using namespace std;
void f(int a[8][8], int current, int x, int y, int size) {
if (size == 1) {
a[x][y] = current;
return;
} else {
size /= 2;
int add_for_each_square = size * size;
f(a, current, x, y, size);
f(a, current + add_for_each_square, x, y + size, size);
f(a, current + 2 * add_for_each_square, x + size, y, size);
f(a, current + 3 * add_for_each_square, x + size, y + size, size);
}
}
int main() {
int a[8][8];
f(a, 1, 0, 0, 8);
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
cout << a[i][j] << " ";
}
cout << endl;
}
}
If the matrix will always be a fixed size, then you can generate two lookup tables for row and column indexes into the matrix. Then, just pass your index through these tables to get the desired positions in the matrix.
const auto MATRIX_SIZE = 8;
const std::array<int, MATRIX_SIZE*MATRIX_SIZE> row_lookup = {{...}}; //put pre-computed values here.
const std::array<int, MATRIX_SIZE*MATRIX_SIZE> col_lookup = {{...}};
for(size_t i = 0; i < MATRIX_SIZE * MATRIX_SIZE; i++)
{
auto val = get_coefficient(i);
auto row = row_lookup[i];
auto col = col_lookup[i];
mat[col][row] = val;
}
I know in C# you can use String.Format method. But how do you do this in C++? Is there a function that allows me to convert a byte to a Hex?? Just need to convert a 8 byte long data to Hex, how do I do that?
If you want to use C++ streams rather than C functions, you can do the following:
int ar[] = { 20, 30, 40, 50, 60, 70, 80, 90 };
const int siz_ar = sizeof(ar) / sizeof(int);
for (int i = 0; i < siz_ar; ++i)
cout << ar[i] << " ";
cout << endl;
for (int i = 0; i < siz_ar; ++i)
cout << hex << setfill('0') << setw(2) << ar[i] << " ";
cout << endl;
Very simple.
Output:
20 30 40 50 60 70 80 90
14 1e 28 32 3c 46 50 5a
Well you can convert one byte (unsigned char) at a time into a array like so
char buffer [17];
buffer[16] = 0;
for(j = 0; j < 8; j++)
sprintf(&buffer[2*j], "%02X", data[j]);
C:
static void print_buf(const char *title, const unsigned char *buf, size_t buf_len)
{
size_t i = 0;
fprintf(stdout, "%s\n", title);
for(i = 0; i < buf_len; ++i)
fprintf(stdout, "%02X%s", buf[i],
( i + 1 ) % 16 == 0 ? "\r\n" : " " );
}
C++:
void print_bytes(std::ostream& out, const char *title, const unsigned char *data, size_t dataLen, bool format = true) {
out << title << std::endl;
out << std::setfill('0');
for(size_t i = 0; i < dataLen; ++i) {
out << std::hex << std::setw(2) << (int)data[i];
if (format) {
out << (((i + 1) % 16 == 0) ? "\n" : " ");
}
}
out << std::endl;
}
You can do it with C++20 std::format which is similar to String.Format in C#:
std::string s = std::format("{:x}", std::byte(42)); // s == 2a
Until std::format is widely available you can use the {fmt} library, std::format is based on (godbolt):
std::string s = fmt::format("{:x}", std::byte(42)); // s == 2a
Disclaimer: I'm the author of {fmt} and C++20 std::format.
Printing arbitrary structures in modern C++
All answers so far only tell you how to print an array of integers, but we can also print any arbitrary structure, given that we know its size. The example below creates such structure and iterates a pointer through its bytes, printing them to the output:
#include <iostream>
#include <iomanip>
#include <cstring>
using std::cout;
using std::endl;
using std::hex;
using std::setfill;
using std::setw;
using u64 = unsigned long long;
using u16 = unsigned short;
using f64 = double;
struct Header {
u16 version;
u16 msgSize;
};
struct Example {
Header header;
u64 someId;
u64 anotherId;
bool isFoo;
bool isBar;
f64 floatingPointValue;
};
int main () {
Example example;
// fill with zeros so padding regions don't contain garbage
memset(&example, 0, sizeof(Example));
example.header.version = 5;
example.header.msgSize = sizeof(Example) - sizeof(Header);
example.someId = 0x1234;
example.anotherId = 0x5678;
example.isFoo = true;
example.isBar = true;
example.floatingPointValue = 1.1;
cout << hex << setfill('0'); // needs to be set only once
auto *ptr = reinterpret_cast<unsigned char *>(&example);
for (int i = 0; i < sizeof(Example); i++, ptr++) {
if (i % sizeof(u64) == 0) {
cout << endl;
}
cout << setw(2) << static_cast<unsigned>(*ptr) << " ";
}
return 0;
}
And here's the output:
05 00 24 00 00 00 00 00
34 12 00 00 00 00 00 00
78 56 00 00 00 00 00 00
01 01 00 00 00 00 00 00
9a 99 99 99 99 99 f1 3f
Notice this example also illustrates memory alignment working. We see version occupying 2 bytes (05 00), followed by msgSize with 2 more bytes (24 00) and then 4 bytes of padding, after which comes someId (34 12 00 00 00 00 00 00) and anotherId (78 56 00 00 00 00 00 00). Then isFoo, which occupies 1 byte (01) and isBar, another byte (01), followed by 6 bytes of padding, finally ending with the IEEE 754 standard representation of the double field floatingPointValue.
Also notice that all values are represented as little endian (least significant bytes come first), since this was compiled and run on an Intel platform.
This is a modified version of the Nibble to Hex method
void hexArrayToStr(unsigned char* info, unsigned int infoLength, char **buffer) {
const char* pszNibbleToHex = {"0123456789ABCDEF"};
int nNibble, i;
if (infoLength > 0) {
if (info != NULL) {
*buffer = (char *) malloc((infoLength * 2) + 1);
buffer[0][(infoLength * 2)] = 0;
for (i = 0; i < infoLength; i++) {
nNibble = info[i] >> 4;
buffer[0][2 * i] = pszNibbleToHex[nNibble];
nNibble = info[i] & 0x0F;
buffer[0][2 * i + 1] = pszNibbleToHex[nNibble];
}
} else {
*buffer = NULL;
}
} else {
*buffer = NULL;
}
}
I don't know of a better way than:
unsigned char byData[xxx];
int nLength = sizeof(byData) * 2;
char *pBuffer = new char[nLength + 1];
pBuffer[nLength] = 0;
for (int i = 0; i < sizeof(byData); i++)
{
sprintf(pBuffer[2 * i], "%02X", byData[i]);
}
You can speed it up by using a Nibble to Hex method
unsigned char byData[xxx];
const char szNibbleToHex = { "0123456789ABCDEF" };
int nLength = sizeof(byData) * 2;
char *pBuffer = new char[nLength + 1];
pBuffer[nLength] = 0;
for (int i = 0; i < sizeof(byData); i++)
{
// divide by 16
int nNibble = byData[i] >> 4;
pBuffer[2 * i] = pszNibbleToHex[nNibble];
nNibble = byData[i] & 0x0F;
pBuffer[2 * i + 1] = pszNibbleToHex[nNibble];
}
Yet another answer, in case the byte array is defined as char[], uppercase and separated by spaces.
void debugArray(const unsigned char* data, size_t len) {
std::ios_base::fmtflags f( std::cout.flags() );
for (size_t i = 0; i < len; ++i)
std::cout << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << (((int)data[i]) & 0xFF) << " ";
std::cout << std::endl;
std::cout.flags( f );
}
Example:
unsigned char test[]={0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
debugArray(test, sizeof(test));
Output:
01 02 03 04 05 06
Use C++ streams and restore state afterwards
This is a variation of How do I print bytes as hexadecimal? but:
runnable
considering that this alters the state of cout and trying to restore it at the end as asked at: Restore the state of std::cout after manipulating it
main.cpp
#include <iomanip>
#include <iostream>
int main() {
int array[] = {0, 0x8, 0x10, 0x18};
constexpr size_t size = sizeof(array) / sizeof(array[0]);
// Sanity check decimal print.
for (size_t i = 0; i < size; ++i)
std::cout << array[i] << " ";
std::cout << std::endl;
// Hex print and restore default afterwards.
std::ios cout_state(nullptr);
cout_state.copyfmt(std::cout);
std::cout << std::hex << std::setfill('0') << std::setw(2);
for (size_t i = 0; i < size; ++i)
std::cout << array[i] << " ";
std::cout << std::endl;
std::cout.copyfmt(cout_state);
// Check that cout state was restored.
for (size_t i = 0; i < size; ++i)
std::cout << array[i] << " ";
std::cout << std::endl;
}
Compile and run:
g++ -o main.out -std=c++11 main.cpp
./main.out
Output:
0 8 16 24
00 8 10 18
0 8 16 24
Tested on Ubuntu 16.04, GCC 6.4.0.
Another C++17 alternative because why not!
std::cout<<std::hex<<std::setfill('0');
struct {
std::uint16_t first{666};
std::array<char,4> second{'a','b','c','d'};
} my_struct;
auto ptr = reinterpret_cast<std::byte*>(&my_struct);
auto buffer = std::vector<std::byte>(ptr, ptr + sizeof(my_struct));
std::for_each(std::begin(buffer),std::end(buffer),[](auto byte){
std::cout<<std::setw(2)<<std::to_integer<int>(byte)<<' ';
});
Executable code here.