String to hex char array [duplicate] - c++

This question already has answers here:
How can I assign hex string to a char[] variable?
(7 answers)
Closed 8 years ago.
I get a string which is given as an argument to a function like e.g. 00112233445566778899aabbccddeeff and I need to make an unsigned char array of it which looks like this:
unsigned char array[16]= {0x00 ,0x11 ,0x22 ,0x33 ,0x44 ,0x55 ,0x66 ,0x77 ,0x88 ,0x99 ,0xaa ,0xbb ,0xcc ,0xdd ,0xee ,0xff};
I have no idea how to do it, tried some things with strcpy and thought about hex but this works only with << or >> as I know so I don't think I know how to apply it here. Anyone could help please?

It seems you need to convert each digit received to a nibble and to combine two nibbles into a byte. The conversion from digit to nibble can be done using a look-up or using conditional logic for digits and letters. The combination is a bitwise shift and a bitwise or.
I could write the code but I've somewhat outgrown assignments, not to mention that my version is unlikely to be a viable solution anyway.

You could do this with a combination of istringstream and std::hex.
example
#include <iostream>
#include <sstream>
int main() {
std::string myStr = "1122AA010A";
std::stringstream ss;
int n;
for(int i = 0; i<myStr.length(); ) {
std::istringstream(myStr.substr(i,2))>>std::hex>>n;
ss<<(char)n;
i += 2;
}
std::string result = ss.str();
std::cout<<"\n"<<result<<"\n";
return 0;
}

Related

Bit manipulation on character string

Can we apply bit manipulation on a character string?
If so, is it always possible to retrieve back a character string from the manipulated string?
I was hoping to use the XOR operator on two strings by converting them to binary and then back to character string.
I took up some code from another StackOverflow question but it only solves half the problem
std::string TextToBinaryString(string words)
{
string binaryString = "";
for (char& _char : words)
{
binaryString +=std::bitset<8>(_char).to_string();
}
return binaryString;
}
I don't know how to convert this string of ones and zeroes back to a string of characters.
I did read std::stio in some google search results as a solution but was not able to understand them.
The manipulation that I wish to do is
std::string message("Hello World");
int n = message.size();
bin_string = TextToBinaryString(message)
std::string left,right;
bin_string.copy(left,n/2,0);
bin_string.copy(right,n,n/2);
std::string result = left^right;
I know I can hardcode this by picking up every entry and applying the operation but it is the conversion of the binary string back to characters that are making me scratch my head.
*EDIT: *I am trying to implement a cipher framework called Feistel cipher (SORRY, should had made that clear before) there they use the property of XOR that when you XOR something with the same thing again it cancels out... For eg. (A^B)^B=A. I wanted to output the ciphered jibberish in the middle. Hence, the query.
Can we apply bit manipulation on a character string?
Yes.
A character is an integer type, so you can do anything to them you can do to any other integer. What happened when you tried?
If so, is it always possible to retrieve back a character string from the manipulated string?
No. It is sometimes possible to recover the original string, but some manipulations are not reversible.
XOR, the particular operation you asked about, is self-reversing, so it works in that case but not in general.
A cheesy example (depends on ASCII character set, don't do this in real code for converting case, etc. etc.)
#include <iostream>
#include <string>
int main() {
std::string s("a");
std::cout << "original: " << s << '\n';
s[0] ^= 0x20;
std::cout << "modified: " << s << '\n';
s[0] ^= 0x20;
std::cout << "restored: " << s << '\n';
}
shows (on an ASCII-compatible) system
original: a
modified: A
restored: a
Note that I'm not converting "a" into "1100001" first, and then using XOR (somehow) zero bit 5 giving "1000001" and then converting that back into "A". Why would I?
This part of your question suggests you don't understand the difference between values and representations: the character is always stored in binary. You can also always treat it as if it is stored in octal, or in decimal, or in hexadecimal - the choice of base only affects how we write (or print) the value, and not what the value is in itself.
Writing a Feistel cipher where the plaintext and key are the same length is trivial:
std::string feistel(std::string const &text, std::string const &key)
{
std::string result;
std::transform(text.begin(), text.end(), key.begin(),
std::back_inserter(result),
[](char a, char b) { return a^b; }
);
return result;
}
This doesn't work at all if the key is shorter, though - looping round the key appropriately is left as an exercise for the reader.
Oh, and printing the encoded string is unlikely to work nicely (unless your key is helpfully just a sequence of space characters, as above).
You probably want something like this:
#include<string>
#include<cassert>
using namespace std;
std::string someBitmanipulation(string words)
{
std::string manipulatedstring;
for (char& thechar : words)
{
thechar ^= 0x5A; // xor with 0x5A
}
return manipulatedstring;
}
int main()
{
std::string original{ "ABC" };
// xor each char of original with 0x5a at put result into manipulated
auto manipulated = someBitmanipulation(original);
// check if manipulating the manipulated string is the same as the original string
assert(original == someBitmanipulation(manipulated));
}
You don't need std::bitset at all.
Now change thechar ^= 0x5A; to say thechar |= 0x5A; and see what happens.

Char seperated by a decimal into a double c++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I am passing a string variable (std::string) and iterating through the string character by character. Whenever I run into a decimal, I want to combine the previous position on the string (i.e 2) and the next position in the string (i.e 5) into a double. So how would I go about making the char 2, char . , char 5 into one whole value (2.5)?
std::double x;
std::string varibleName = "4 5 7 2.5";
for (int i = 0; i < variableName.length(); i++) // iterates through variableName
{
if (variableName[i] == '.'){ // if the current position of the iteration is a decimal, I want to grab the char before the decimal and the char after the decimal so I can combine all three positions of the string making it 2.5 and not 25.
}
}
Well, you are wildly overthinking it. The C++ library provides std::stof, std::stod, std::stold that does exactly what you want. Convert a string like "2.5" to a float, double or long double, e.g.
#include <iostream>
int main (void) {
std::string s = "2.5";
double d = std::stod(s);
std::cout << d << "\n";
}
Example Use/Output
$ ./bin/stodex
2.5
Look things over and let me know if you have further overthinking questions.
Note that giving an example, code snips, and error logs make troubleshooting a lot easier :)
It sound like you have some input like "2.1" and need to convert it to a double like 2.1?
If that is the case you can use the <cstdlib> atof function.
Example:
/* atof example: sine calculator */
#include <stdio.h> /* printf, fgets */
#include <stdlib.h> /* atof */
#include <math.h> /* sin */
int main ()
{
double n;
char buffer[256];
printf ("Enter degrees: ");
fgets (buffer,256,stdin);
n = atof (buffer);
printf ("You entered %s which is a double like %f\n" , buffer, n);
return 0;
}

Unexpected results when using std::stringstream

I am a beginner in C++, started last week. I am trying to make a simple program converting a number of inches to foot inch notation: E.g. 62 turns into 5'2". However when I try to compile I have some error in line 8. I don't know what it is. Thanks in advance.
#include <iostream>
#include <sstream>
using namespace std;
string ConvertToFootInchMeasure (int totalInches){
string feet = ""+totalInches/12;
string inches = "" + totalInches%12;
stringstream converted;
conveted<<feet;
converted<<"'";
converted<<inches;
converted<<"\"";
return converted.str();
}
That code can be easily fixed like this:
string ConvertToFootInchMeasure (int totalInches){
stringstream converted;
// Do inline calculations and use formatted text output for the results
converted << (totalInches/12) << "'" << (totalInches%12) << "\"";
return converted.str();
}
To explain further: You tried to concatenate the numeric results of the totalInches/12 and totalInches%12 operations to a std::string variable, but the right side of the statement doesn't do that.
Note:
std::string operator+(std::string, char c) doesn't do conversion of numerics to string and concatenation as you tried to use with:
string feet = ""+totalInches/12;
also it seems to be even worse in your case because the term
""+totalInches/12
does pointer arithmetics for a const char* pointer, and the string variable is initialized from e.g. a pointer address "" + (62/12).

Check input is a valid integer [duplicate]

This question already has answers here:
How to determine if a string is a number with C++?
(36 answers)
Closed 10 months ago.
Hi Can anyone help me please. I need to check that my input only contains integers. Im guessing from looking it up that I use the isDigit function but I am not sure how to use this to check the whole number.
I'm using C++ to interact with MSI so i'm getting the integer as follows:
hr = WcaGetProperty(L"LOCKTYPE",&szLockType);
ExitOnFailure(hr, "failed to get the Lock Type");
I think i have to change szLockType to a char and then use isdigit to scan through each character but i am not sure how to implement this. Any help would be greatly appreciated. P.s im a beginner so please excuse if this is a really trivial question..:)
Use std::stoi(). You'll get an exception if the string is not an integer value.
What's the type of szLockType?
Is it a a null-terminated char-string?
Then you can use the array syntax to get individual characters.
for(int i = 0; i < std::strlen(szLockType); i++) {
if(!std::isDigit(szLockType[i])) {
// it contains a non-digit - do what you have to do and then...
break; // ...to exit the for-loop
}
}
Or is it a std::string? Then the syntax is slightly different:
for(int i = 0; i < szLockType.length(); i++) {
if(!std::isDigit(szLockType.at(i)) {
// it contains a non-digit - do what you have to do and then...
break; // ...to exit the for-loop
}
}
Even better, with modern C++ you can do this:
#include <algorithm>
#include <cctype>
auto lambda = [](auto elem)
{
return std::isdigit(elem);
};
return std::all_of(szLockType, szLockType + strlen(szLockType), lambda);
Your choice as to whether you prefer a named lambda or regular, anonymous lambda.
FYI it is std::isdigit rather than isDigit.
https://en.cppreference.com/w/cpp/string/byte/isdigit

Is there analog in C++ for Python's file.read(2)?

I'm currently trying to make analog of Python's function:
def read_two_symbols(fdescr):
return(file.read(2))
myfile = open('mytext.txt', 'rb')
two_symbols = read_two_symbols(myfile)
print(two_symbols)
Is there any way to do it in C++? That's what I've tried:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
string read_two_bytes(fstream file)
{
string byte1, byte2;
byte1 = file.get();
byte2 = file.get();
string two_bytes = byte1 + byte2;
return two_bytes;
}
int main()
{
fstream myfile("mytext.txt", ios_base::in | ios_base::binary);
string two_bytes = read_two_bytes(myfile);
cout << two_bytes << endl;
return 0;
}
However it fails. :-( How can I do it using C++?
#vivek has pointed out that you can't pass an fstream "by value". Passing things by value makes copies of them (or rather, runs their copy constructor, which may or may not actually make a "deep" copy of them).
Once you fix that, iostreams are actually cute and cuddly. They can detect the type you're asking for and read just that amount of data. If it's a char and you use the stream operators, it'll read a byte's worth:
string read_two_bytes(fstream& file)
{
char byte1, byte2;
file >> byte1 >> byte2;
string two_bytes;
two_bytes += byte1;
two_bytes += byte2;
return two_bytes;
}
#Nim seems to be trying to give you a generalized answer, perhaps to show off C++ vs Python. It's more answering the question for "N-bytes", except he hardcoded 2 so it just looks like overkill. It can be done easier, but nice to know the flexiblity is there...no?
If you're new to C++ I/O you might find the answer to this question I bothered to write the other day to be interesting as a contrast to the methods being suggested by other answers:
Output error when input isn't a number. C++
use the read or readsome function in istream. e.g
std::vector<char> buffer(2, 0);
if (myfile.read(&buffer[0], 2))
std::copy(buffer.begin(), buffer.end(), std::ostream_iterator<int>(std::cout, ""));
Change the function definition to this ( notice the & sign):
string read_two_bytes(fstream & file)