How can I correctly convert this to hex? - c++

I have an issue where I am trying to convert numbers to hex with the following code.
int numconvert(string hexnum)
{
stringstream converter(hexnum);
unsigned int value = 0;
converter >> hex >> value;
return value;
}
string hexconvert(int hexnum)
{
stringstream ss;
ss << hex << hexnum;
string n;
ss >> n;
return n;
}
I use the numconvert to change an input from string to int, then I use hexconvert, to change that into a hex and store it as a string.
Everything seems to work just fine but then for some reason, when I pass it 4096, it gives me back 4096. I was expecting 1000 but I am not sure why it is erroring out on me. I give it 4096 and I notice that it returns an int of 16534, then the program sends that over to the hexconvert and it returns 4096, which, technically is right, but not what I wanted.
It seems to handle other numbers just fine. What am I doing wrong here?

I think you got an logic error there. If you write:
int n = numconvert("4096");
std::string s = hexconvert(n);
you basically tell it to interpret "4096" already as hex number because you got converter >> hex >> value; inside numconvert, translating it back to hex would always lead to the same getting returned.
What you want is probably
int n = std::stoi("4096");
std::string s = hexconvert(n);
This will interpret "4096" as a normal base 10 number and then convert that to a hex string again using your hexconvert.
That said your numconvert can be written shorter and probably a bit more efficient using std::stoi too, it's basically just:
int numconvert(const std::string& str)
{
return std::stoi(str, nullptr, 16);
}
we don't need the second argument so we pass nullptr, the 3rd argument is the base.

Try using the str member instead of the extract operator, to eject the string from the stringstream. Besides being more direct, you don't have to worry about how the extractor further interprets things.

Related

Problem with reading a std::vector from a txt file (reads only one number)

I have a problem that the part of the internet that I went through can't solve.
It's my very first encounter with fstream and no matter what I do the program won't import more than one integer from the text file. I'd love if anyone with knowledge could help me a little. Here is the code that I'm using at the moment.
Writing:
void writeVector(const std::vector<int>& vec, const std::string& fileName) {
std::ofstream save;
save.open(fileName);
if (save) {
for (int i = 0; i < vec.size(); ++i) {
save << &vec[i];
}
std::cout << "Plik zapisano pomyslnie.\n";
}
save.close();
}
Reading:
std::vector<int> readVector(const std::string& fileName) {
std::ifstream read(fileName);
std::vector<int> buffer;
if (read) {
int value;
while (read >> value) {
buffer.push_back(value);
}
}
return buffer;
}
void zad4() {
std::string fileName = "Zadanie 2";
print(readVector(fileName));
}
Plus what's bothering me is the code in the txt file since it is something like: (00000248EC48FE5000000248EC48FE5400000248EC48FE5800000248EC48FE5C etc).
When I print "buffer" it only gives me one number. I have made sure that the vector is correctly initialized. What can be the problem?
Short answer: (credit: Sam Varshavchik)
if (save) {
for (int i = 0; i < vec.size(); ++i) {
save << vec[i] << ' ';
}
The data in the file looks like a string of hexadecimal values. Your attempt to read this data tries to read it using decimal. As it starts of with a decimal digit and the sequence of decimal digits don't exceed the maximal value for int the read attempt manages to get one value. That is almost certainly not what you'd actually want to do with this data.
Now, what to actually do with this data is a separate question. You may want to read suitable groups of hex characters into corresponding integers. Whether that is the correct thing to do depends on what the data is supposed to mean. There seems to be a repeating pattern in the section you quoted (rewritten with the string broke after 16 character/8 bytes):
00000248EC48FE50
00000248EC48FE54
00000248EC48FE58
00000248EC48FE5C
That seems to imply that the data contains some sort of 64 bit data spelled in hex. The formatted input used by IOStreams really likes to get spaces. One way to decode this data is to read it into a buffer with 16 characters, update a string stream with this data, and read data from there as hex data:
std::istringstream sin;
sin >> std::hex;
char buffer[16];
while (read.read(buffer, 16)) {
sin.str(std::string(buffer, buffer + read.gcount()));
sin.clear();
std::uint64_t value;
if (!(sin >> value)) {
break;
}
buffer.push_back(value);
}

How to convert a hexadecimal string to long in c++

I have a string which is as shown below.
std::string myString = "0005105C9A84BE03";
I want the exact data to be saved on some integer say "long long int"
long long int myVar = 0005105C9A84BE03;
When i print myVar i'm expecting output 1425364798979587.
I tried to use atoi, strtol stroi, strtoll but nothing worked out for me.
Any idea how to solve it?
The following should work:
#include <iostream>
#include <sstream>
int main()
{
std::string hexValue = "0005105C9A84BE03"; // Original string
std::istringstream converter { hexValue }; // Or ( ) for Pre-C++11
long long int value = 0; // Variable to hold the new value
converter >> std::hex >> value; // Extract the hex value
std::cout << value << "\n";
}
This code uses an std::istringstream to convert from std::string to long long int, through the usage of the std::hex stream manipulator.
Example
There is a list of functions to convert from string to different integer types like:
stol Convert string to long int (function template )
stoul Convert string to unsigned integer (function template )
strtol Convert string to long integer (function )
They are some more. Please take a look at http://www.cplusplus.com/reference/string/stoul At the end of the documentation you find alternative functions for different data types.
All they have a "base" parameter. To convert from hex simply set base=16.
std::cout << std::stoul ("0005105C9A84BE03", 0, 16) << std::endl;

C++ : Trim a string to a single char, then turn that char into a float

I'm writing a program that takes a polynomial expression from a file, and then solves the polynomial using the variable provided. Example :
f(5.0) = 7x^2 – 9
So basically I'm extracting a file line by line by doing :
string line;
getline(inputfile,line);
Now, I need to get the variable inside of f (in this case 5) and set that equal to a float which I've named variable. I'm aware of atof (I'm using minGW 4.9.2 [required for my programming class]) so I can't use stof. My current attempt at extracting this float looks like this :
float variable;
for(int i = 0; i<line.length(); i++) {
if(isdigit(line[i]) {
variable = atof(line[i]) // THE ERROR IS HERE
break; // so we only get the first digit
}
}
I'm pretty lost here, not sure what to do. I just need to set that 5.0 (or whatever it may be) equal to my variable float. Any help is appreciated.
It probably does duty for your intent.
string str = "f(5.0) = 7x^2 – 9";
string startDEL = "(";
string stopDEL = ")";
unsigned first = str.find(startDEL);
unsigned last = str.find(stopDEL);
string strNew = str.substr (first+1,last-first-1);
std::cout << << atof(strNew.c_str()) << std::endl;
You can use a std::streamstream, which allows you to treat a std::string as a stream:
std::string str;
std::getline(inputfile, str);
std::istringstream is(str);
float f, char x, char op, float second_var;
is >> f >> x >> op; >> second_var; // Read 7, then x, then ^, then 2.
Maybe the shortest solution is to use std::stringstream:
char dummy;
double variable;
std::stringstream("f(5.2) = 7x^2-9") >> dummy >> dummy >> variable;
This will read the first two chars into dummy and the following numeric value into variable.
You have to #include <sstream> to be able to use std::stringstream.
try strtof instead of atof(), since atof() returns a double instead of a float

What exactly does stringstream do?

I am trying to learn C++ since yesterday and I am using this document: http://www.cplusplus.com/files/tutorial.pdf (page 32). I found a code in the document and I ran it. I tried inputting Rs 5.5 for price and an integer for quantity and the output was 0.
I tried inputting 5.5 and 6 and the output was correct.
// stringstreams
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main ()
{
string mystr;
float price = 0;
int quantity = 0;
cout << "Enter price: ";
getline (cin,mystr);
stringstream(mystr) >> price;
cout << "Enter quantity: ";
getline (cin,mystr);
stringstream(mystr) >> quantity;
cout << "Total price: " << price*quantity << endl;
return 0;
}
What exactly does the mystring command do? Quoting from the document:
"In this example, we acquire numeric values from the standard input
indirectly. Instead of extracting numeric values directly from the
standard input, we get lines from the standard input (cin) into a
string object (mystr), and then we extract the integer values from
this string into a variable of type int (quantity)."
My impression was that the function will take an integral part of a string and use that as input.
Sometimes it is very convenient to use stringstream to convert between strings and other numerical types. The usage of stringstream is similar to the usage of iostream, so it is not a burden to learn.
Stringstreams can be used to both read strings and write data into strings. It mainly functions with a string buffer, but without a real I/O channel.
The basic member functions of stringstream class are
str(), which returns the contents of its buffer in string type.
str(string), which set the contents of the buffer to the string argument.
Here is an example of how to use string streams.
ostringstream os;
os << "dec: " << 15 << " hex: " << std::hex << 15 << endl;
cout << os.str() << endl;
The result is dec: 15 hex: f.
istringstream is of more or less the same usage.
To summarize, stringstream is a convenient way to manipulate strings like an independent I/O device.
FYI, the inheritance relationships between the classes are:
From C++ Primer:
The istringstream type reads a string, ostringstream writes a string, and stringstream reads and writes the string.
I come across some cases where it is both convenient and concise to use stringstream.
case 1
It is from one of the solutions for this leetcode problem. It demonstrates a very suitable case where the use of stringstream is efficient and concise.
Suppose a and b are complex numbers expressed in string format, we want to get the result of multiplication of a and b also in string format. The code is as follows:
string a = "1+2i", b = "1+3i";
istringstream sa(a), sb(b);
ostringstream out;
int ra, ia, rb, ib;
char buff;
// only read integer values to get the real and imaginary part of
// of the original complex number
sa >> ra >> buff >> ia >> buff;
sb >> rb >> buff >> ib >> buff;
out << ra*rb-ia*ib << '+' << ra*ib+ia*rb << 'i';
// final result in string format
string result = out.str()
case 2
It is also from a leetcode problem that requires you to simplify the given path string, one of the solutions using stringstream is the most elegant that I have seen:
string simplifyPath(string path) {
string res, tmp;
vector<string> stk;
stringstream ss(path);
while(getline(ss,tmp,'/')) {
if (tmp == "" or tmp == ".") continue;
if (tmp == ".." and !stk.empty()) stk.pop_back();
else if (tmp != "..") stk.push_back(tmp);
}
for(auto str : stk) res += "/"+str;
return res.empty() ? "/" : res;
}
Without the use of stringstream, it would be difficult to write such concise code.
To answer the question. stringstream basically allows you to treat a string object like a stream, and use all stream functions and operators on it.
I saw it used mainly for the formatted output/input goodness.
One good example would be c++ implementation of converting number to stream object.
Possible example:
template <class T>
string num2str(const T& num, unsigned int prec = 12) {
string ret;
stringstream ss;
ios_base::fmtflags ff = ss.flags();
ff |= ios_base::floatfield;
ff |= ios_base::fixed;
ss.flags(ff);
ss.precision(prec);
ss << num;
ret = ss.str();
return ret;
};
Maybe it's a bit complicated but it is quite complex. You create stringstream object ss, modify its flags, put a number into it with operator<<, and extract it via str(). I guess that operator>> could be used.
Also in this example the string buffer is hidden and not used explicitly. But it would be too long of a post to write about every possible aspect and use-case.
Note: I probably stole it from someone on SO and refined, but I don't have original author noted.
You entered an alphanumeric and int, blank delimited in mystr.
You then tried to convert the first token (blank delimited) into an int.
The first token was RS which failed to convert to int, leaving a zero for myprice, and we all know what zero times anything yields.
When you only entered int values the second time, everything worked as you expected.
It was the spurious RS that caused your code to fail.

c++, get phone number from txt file

I'm trying input a phone number in the format: 555-555-5555 into a struct with three int's. I've tried using getline with a delimiter of "-", but I keep getting the error: "cannot convert parameter 1 from 'int' to 'char *'".
I tried creating a temp char* variable to store the number in and then type casting it to int, but that didn't work.
How should I go about doing this?
Thanks
edit:
here's some of the code:
void User::Input(istream& infile) {
char* phone_temp;
...
infile.getline(phone_temp, sizeof(phoneNum.areaCode), "-");
phoneNum.areaCode = (int)phone_temp;
...
}
Since you are posting this as a c++ question, and not a c question, Use istringstream
http://www.cplusplus.com/reference/iostream/istringstream/
From my head it your code would become something like:
std::string sPhoneNum("555-555-5555");
struct
{
int p1;
int p2;
int p3;
} phone;
char dummy;
std::istringstream iss(sPhoneNum);
iss >> phone.p1; // first part
iss >> dummy; // '-' character
iss >> phone.p2; // second part
iss >> dummy; // '-' character
iss >> phone.p2; // last part
EDIT:
now that you have posted example code, I see you already start with an istream, you can just use the >> operator directly, no need to create another istringstream operator. See examples: http://www.cplusplus.com/reference/iostream/istream/operator%3E%3E/
Also, stay away from c-style conversion methods with char * and atoi stuff if you don't have to, working with std::string and istreams is the "right" C++ way. It avoids memory leaks and other nasty problems.
Reading a phone number from a stream:
Assuming the number is well formatted:
void User::Input(istream& infile)
{
int part1;
int part2;
int part3;
char dash1;
char dash2;
infile >> part1 >> dash1 >> part2 >> dash2 >> part3;
/*
* !infile will return false if the file is in a bad state.
* This will happen if it fails to read a number from
* the input stream or the stream ran out of data.
*
* Both these conditions constitute an error as not all the values will
* be set correctly. Also check that the dash[12] hold the dash character.
* Otherwise there may be some other formatting problem.
*/
if ((!infile) || (dash1 != '-') || (dash2 != '-'))
{
throw int(5); // convert this to your own exception object.
}
}
if I understand correctly, try atoi() or stringstream to convert from char* to int
See this example on how you can tokenize the line. This question will also help.
Then use atoi to convert string to int.
You can't cast a char* to an int and expect a correct value. A char* is an address in memory, so when you cast it to int, you'll get a memory address in your int. You need to call a function, such as atoi() to algorithmically convert the data char* is pointing to into an integer.
Another viable option, although not quite C++, is:
char a[10],b[10],c[10];
scanf("%d-%d-%d", a, b, c);
It appears you're trying to convert a char to an integer, in which case you'd want to use the atoi function or a string stream.
rather than using infile.getline() use the free standing version with a std::string:
getfile(infile, buffer);
After that, if you'd like you can do an addition getline():
istringstream phonenumber(buiffer);
string areacode = getline(phonenumber, part1. '-');
or you can use the extractor >> (that's what it's for!)
int areacode;
phonenumber >> areacode;
Just a side note: if you're using char* do make sure you allocate space for it, or at least point to allocated space.