I need to parse an std::string containing a number in binary format, such as:
0b01101101
I know that I can use the std::hex format specifier to parse numbers in the hexadecimal format.
std::string number = "0xff";
number.erase(0, 2);
std::stringstream sstream(number);
sstream << std::hex;
int n;
sstream >> n;
Is there something equivalent for the binary format?
You can use std::bitset string constructor and convert bistet to number:
std::string number = "0b101";
//We need to start reading from index 2 to skip 0b
//Or we can erase that substring beforehand
int n = std::bitset<32>(number, 2).to_ulong();
//Be careful with potential overflow
You can try to use std::bitset
for example:
skip two first bytes 0b
#include <bitset>
...
std::string s = "0b0111";
std::bitset<4>x(s,2); //pass string s to parsing, skip first two signs
std::cout << x;
char a = -20;
std::bitset<8> x(a);
std::cout << x;
short b = -427;
std::bitset<16> y(c);
std::cout << y;
Related
I suppose the fact that uint8_t is really just an alias for char means that when the characters in the stringstream get read back in, they are stored natively, i.e. the ascii code for the character, whereas if the char is input to an int, with std::hex specified, it gets read in as a hex digit converted to base 10.
This is a small example exhibiting the behavior, but the reason I'm asking is because I started out under the assumption that specifying an output vector of unit8_t was the right approach, as I need to later feed this vector as an array to a C function as a byte vector (you pass it in as a void pointer and it figures out what do to with it somehow). So I figured reading in pairs of input chars into a string stream and then out into a uint8_t would help me skip manually bitshifting. Is there a way of keeping the idea of reading into a uint8_t but evoking the handling of an int? Can I cast to int at the point of the read from the stringstream? Or what?
#include <iostream>
#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <vector>
#include <cstdint>
int main (int argc, char** argv) {
uint8_t n = 0;
std::stringstream ss;
ss << 'F';
ss >> std::hex >> n;
std::cout << "uint8:" << (int)n << std::endl;
int m = 0;
std::stringstream tt;
tt << 'F';
tt >> std::hex >> m;
std::cout << "int:" << std::hex << m << std::endl;
return 0;
}
output
uint8:70
int:f
There are operator>> overloads for char, signed char and unsigned char, which all read a single character from the stream. A uint8_t argument selects the unsigned char overload as the best match, reading F as a character (ASCII code 70 or 0x46).
To match an integer extraction operator>> overload, use an argument of type short or bigger (for example, uint16_t):
uint16_t n = 0;
std::stringstream ss;
ss << 'F';
ss >> std::hex >> n;
Can I cast to int at the point of the read from the stringstream?
No. The argument is taken by reference, which in function calls works as a pointer. Type punning a uint8_t argument as (int&) will invoke undefined behavior. Just use a bigger type instead.
I'm trying to control the number of Digits i add in a String , but I couldn't control it since i am printing an Array of Strings .
float loads[n] = { 1,2,3,0.05,1,2,3,0.5,1,2,3,3,1,2 };
string print[nBits] = { "" };
int n=14;
int BB;
.
.
.
void main(){
for (int j = 0; j < nBits; ++j)// 2^n
{
for (int i = 0; i < n; ++i) // n
{
BB = arr[j][i];
R = loads[i];
if (BB == 1) {
print[j]+="" +std::to_string(loads[i])+"//";
}
}
}
But i eventually get an Array of strings that Looks like this :
0.050000//3.000000//...
Is there any way to control the Precision of the floating number before adding it to the String ?
(so i can have a resulting string control a fixed number of Digits instead)
0.05//3.00// ...
Use std::stringstream together with std::fixed and std::setprecision(n).
http://en.cppreference.com/w/cpp/io/manip
You can use the standard streaming mechanic:
streams
You can use ostream to generate the string:
#include <ostream>
#include <sstream>
#include <iomanip>
std::ostringstream stream;
for(...) {
stream << loads[i] << "//";
}
std::string str = stream.str();
The idea is to generate a stream that you can stream strings too. You can then generate a std::string out of it, using stream.str(). Streams have default values for how to convert numbers. You can influence this with std::setprecision and std::fixed as well as other variables (for more info, see the C++ stdlib reference).
Using std::setprecision and std::fixed.
std::ostringstream stream;
// set the precision of the stream to 2 and say we want fixed decimals, not
// scientific or other representations.
stream << std::setprecision(2) << std::fixed;
for(...) {
stream << loads[i] << "//";
}
std::string str = stream.str();
You find another example here.
sprintf
You can always go the C way and use sprintf although it's discouraged as you have to provide a buffer of correct length, e.g.:
char buf[50];
if (snprintf(buf, 50, "%.2f", loads[i]) > 0) {
std::string s(buf);
}
I have a program that reads the hex of a file, modifies it, and stores the modified hex in a std::string.
For example, how would I write this to a file
std::string wut="b6306edf953a6ac8d17d70bda3e93f2a3816eac333d1ac78";
and get its value
.0n..:j..}p...?*8...3..x
in the outputted file?
I'd prefer not to use sprintf, but I guess if it's necessary, I'll do what I must.
If I understand your question correctly you want the text converted to it's numeric equivalent and then written to file. Given the hint you provided in your question it looks like this should be done byte by byte. Below is one way to achieve this. Note the need to convert each byte from a string to an integer value.
#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <ios>
std::string wut = "b6306edf953a6ac8d17d70bda3e93f2a3816eac333d1ac78";
int main()
{
std::ofstream datafile("c:\\temp\\temp1.dat", std::ios_base::binary | std::ios_base::out);
char buf[3];
buf[2] = 0;
std::stringstream input(wut);
input.flags(std::ios_base::hex);
while (input)
{
input >> buf[0] >> buf[1];
long val = strtol(buf, nullptr, 16);
datafile << static_cast<unsigned char>(val & 0xff);
}
}
The answer of #Peter R will lead to an output which is not 100% equal, due to the stringstream interpreting more than one '0's in a row in an unintended way.
Example: If we want to write the hex value "00000000", the stringstream would output " 000000".
The solution below works in every case, no matter how many zeros are contained in the hex string:
// Input
std::string hex = "180f00005e2c3415"; // (or longer)
std::basic_string<uint8_t> bytes;
// Iterate over every pair of hex values in the input string (e.g. "18", "0f", ...)
for (size_t i = 0; i < hex.length(); i += 2)
{
uint16_t byte;
// Get current pair and store in nextbyte
std::string nextbyte = hex.substr(i, 2);
// Put the pair into an istringstream and stream it through std::hex for
// conversion into an integer value.
// This will calculate the byte value of your string-represented hex value.
std::istringstream(nextbyte) >> std::hex >> byte;
// As the stream above does not work with uint8 directly,
// we have to cast it now.
// As every pair can have a maximum value of "ff",
// which is "11111111" (8 bits), we will not lose any information during this cast.
// This line adds the current byte value to our final byte "array".
bytes.push_back(static_cast<uint8_t>(byte));
}
// we are now generating a string obj from our bytes-"array"
// this string object contains the non-human-readable binary byte values
// therefore, simply reading it would yield a String like ".0n..:j..}p...?*8...3..x"
// however, this is very useful to output it directly into a binary file like shown below
std::string result(begin(bytes), end(bytes));
Then you can simply write this string to a file like this:
std::ofstream output_file("filename", std::ios::binary | std::ios::out);
if (output_file.is_open())
{
output_file << result;
output_file.close();
}
else
{
std::cout << "Error could not create file." << std::endl;
}
I have a txt file which contains integers in hexadecimal form in each line like:
232B2344
A2BC34893
DEF9433
.....
I would like an elegant way of reading this .txt file in C++ and store them in arrays so that I can make computations on them. Also given the hex 232B2344 say I would like to be in position to say the value of each byte entry
First include a header
#include "sstream"
Then get the hexadecimal value in a simple char[] array string using file handling.
char str[100];
Declare an Unsigned int variable...
unsigned int value;
Then declare a "std::stringstream" variable. e.g.
std::stringstream ss;
ss<<std::hex<<str;
ss>>value;
Now the "value" contains the hexadecimal value in file in form of integer.
As far as you describe, each number in the file is a 4 bytes unsigned integer (that fit in 32 bits). Here you have a c++ version for parsing the file and getting the numbers array:
std::vector<std::string> fromFileToArray( const std::string & fileName )
{
std::string line;
std::vector<uint32_t> numbers;
std::stringstream ss;
uint32_t tmp;
std::ifstream numbersFile( fileName.c_str() );
while( numbersFile.good() )
{
getline( numbersFile, line );
ss << std::hex << line;
ss >> tmp;
numbers.push_back( tmp );
}
}
How about this (though it is written with C function, one could help me port this to use C++ functions):
const char hexstring[] = "deadbeef10203040b00b1e50", *pos = hexstring;
unsigned char val[12];
size_t count = 0;
/* WARNING: no sanitization or error-checking whatsoever - MAGIC. DO NOT TOUCH. */
for(count = 0; count < sizeof(val)/sizeof(val[0]); count++) {
sscanf(pos, "%2hhx", &val[count]);
pos += 2 * sizeof(char);
}
/* Does it work? */
printf("0x");
for(count = 0; count < sizeof(val)/sizeof(val[0]); count++)
printf("%02x", val[count]);
printf("\n");
In case of an odd number of hex digits in the string, you have to make sure you prefix it with a starting 0. For example, the string "f00f5" will be evaluated as {0xf0, 0x0f, 0x05} erroneously by the above example, instead of the proper {0x0f, 0x00, 0xf5}.
To read value in hex format - use std::hex from <iomanip>. Like in this very short example:
#include <iostream>
#include <iomanip>
int main() {
int value;
std::cin >> std::hex >> value;
std::cout << value;
}
Just read as many times as your array has elements.
i have a unicode mapping stored in a file.
like this line below with tab delimited.
a 0B85 0 0B85
second column is a unicode character. i want to convert that to 0x0B85 which is to be stored in int variable.
how to do it?
You've asked for C++, so here is the canonical C++ solution using streams:
#include <iostream>
int main()
{
int p;
std::cin >> std::hex >> p;
std::cout << "Got " << p << std::endl;
return 0;
}
You can substitute std::cin for a string-stream if that's required in your case.
You could use strtol, which can parse numbers into longs, which you can then assign to your int. strtol can parse numbers with any radix from 2 to 36 (i.e. any radix that can be represented with alphanumeric charaters).
For example:
#include <cstdlib>
using namespace std;
char *token;
...
// assign data from your file to token
...
char *err; // points to location of error, or final '\0' if no error.
int x = strtol(token, &err, 16); // convert hex string to int