Store a string of hex into a char? - c++

so I have a string that has a hex value in it. For example, my string may have
string a = "0x4D";
Would it be possible to assign 0x4D to a char? Because I know that if I had
char c = 0x4D
then I could print out its ASCII symbol, which would be M.
Is it possible to store "0x4D" into a char so that I can print out its ascii symbol? If anyone has any tips, that would be appreciated! If there's a better way to do this, please let me know! Thanks!

You can use strtol to convert the string to a number. You can then print this number or do other things you like with it.
Oh wait, you tagged it C++, and strtol is very much C-style. In C++, you can use a stringstream, and extract a number from it.

You can use std::stoi to convert the string to an integer (the base is auto-detected from the 0x prefix):
std::string str = "0x4D";
char c = static_cast<char>(std::stoi(str));
std::cout << c << std::endl;
However, this is not guaranteed to give you the ASCII character for that value. There are various translations between character sets that occur in this simple code alone. For example, the chars in the string literal "0x4D" are initialized with the corresponding value in the implementation-defined execution character set. The printed character is also up to interpretation by the medium that is displaying it.
The best you could do is provide a mapping from ASCII values to characters. You could do this with an array where the index is the ASCII value and the element is the corresponding character.

To use stringstreams as Bas suggests:
int x;
string s = "0x10";
stringstream ss;
ss << hex << s;
ss >> x;
But I think it's a wasteful way to do it.

Here is a solution based on std::stringstream:
std::istringstream iss ("0x4D");
iss.flags(std::ios::hex);
int i;
iss >> i;
std::cout << "[" << (char)i << "]" << std::endl; //--> prints "[M]"

Related

Converting int to string and adding to an existin string in c++

I was wondering how I could convert an int to a string and then add it to an existin string. i.e.
std::string s = "Hello";
//convert 1 to string here
//add the string 1 to s
I hope I'm making sense. Thank you very much in advance for any answer.
If the number you want to append is an integer or floating point variable, then use std::to_string and simply "add" it:
int some_number = 123;
std::string some_string = "foo";
some_string += std::to_string(some_number);
std::cout << some_string << '\n';
Should output
foo123
The "modern" way is to use std::to_string(1). In fact, various overloads of std::to_string exist for different number types.
Putting this together you can write std::string s = "Hello" + std::to_string(1);
Alternatively you can use std::stringstream which can be faster due to fewer string concatenation operations which can be expensive:
std::stringstream s;
s << "Hello" << 1;
// s.str() extracts the string

Struggling with a textcounter

I tried to write myself a textcounter which tells me how many characters and words are in a piece of text. Every time I try to paste in a long piece of text for it to count, it will crash or display something random.
Does anyone have any suggestions?
This is what I have written:
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "Text counter\nPlease insert text.\n";
string text = "";
getline(cin, text);
double countTotal = text.size();
cout << "Total characters: " << countTotal << "\n";
int wordCount = 1;
for (int chrSearch = 0; chrSearch < (int)text.size(); chrSearch++)
{
char chr = text.at(chrSearch);
if(chr == ' ')
{
wordCount++;
}
}
cout << "Total words: " << wordCount << "\n";
return 0;
}
First of all, the code reads at most one line: std::getline(std::cin, line) stops reading upon receiving the first newline. You can specify a character where to stop, e.g, the character '\0' is unlikely to be present in typical text. For example, you could use:
std::string text;
if (std::getline(std::cin, text, '\0')) {
// do something with the read text
}
You should also always check that input was successful. While the above would work with short texts, when the texts become large it makes more sense to read them one line at a time and eventually reading a line will fail when the end of the stream is reached.
In case you don't like the approach of reading everything up to a null character, you could read the entire stream using code like this:
std::istreambuf_iterator<char> it(std::cin), end;
std::string text(it, end);
if (!text.empty()) {
// do something with the read text
}
A few notes on the other parts of the code:
Don't use double where you mean to use an integer. You may want to use a bigger integer, e.g., unsigned long or unsigned long long but double is for floating point values.
When iterating through a sequence you should either use an unsigned integer type when dealing with indices, e.g., unsigned int or std::size_t. This way there is no need to cast the size(). Preferably you'd use iterators:
for (auto it(text.begin()), end(text.end()); it != end; ++it) {
char chr(*it);
// ...
}
or
for (char chr: text) {
// ...
}
Note that your word count is wrong if there are two consecutive spaces. Also, if you don't break your text using line breaks, you need to use '\n' as an additional whitespace character separating words. If you want to consider all spaces, you should actually use something like this to determine if a character is a space:
if (std::isspace(static_cast<unsigned char>(chr)) { ... }
The static_cast<unsigned char>(chr) is needed because char tends to be signed and using a negative value with std::isspace() results in undefined behavior. Casting the character to unsigned char avoids any problems. Note that negative characters are not entirely uncommon: for example, the second character of my last name (the u-umlaut 'ü') normally result in a negative char, e.g., when UTF-8 or ISO-Latin-1 encoding is used.

fstream not creating text file

It seems when I try to run this source of code, instead of making an Attempt1.txt, or Attempt2.txt, or Attempt3.txt, it simply just makes a FILE named Attempt.
string str;
int num_attempts_x_million = 1;
str = "Attempt";
str += num_attempts_x_million;
str += ".txt";
textfile.open(str);
textfile << password << endl;
textfile.close();
You might be appending control characters, not 'regular' characters. This is assuming, of course, that the type of num_attempts_x_million is an int (or any integer type).
std::string::operator+= does not have an overload for int. Instead, it has one for char so it casts it into a char first and then appends it. For low integer values, this ends up with things like 0x0, 0x1, 0x2, etc which are known as control characters in ASCII.
In order for you to convert the integer into a string you have to use std::to_string.
str = "Attempt";
str += std::to_string(num_attempts_x_million);
str += ".txt";
textfile.open(str);
textfile << password << endl;
textfile.close();

How to convert a string to its unicode escapes?

I'm trying to convert a char array to unicode-escapedchar array.
Say I have a string "C:/İmüp".
How can I convert it to C:/\u0130m\u00fcp as char array or const char?
(I get "C:/Hello İmüp" as char array via ExpandEnvironmentStrings(), then i need to write that to a file with its unicode escapes)
I tried typecast converting, std::stringstream and ASCII tables, looked up for examples on C++ json encoders, however i couldn't get it working
Try this:
std::wstring env;
// fill env with data from ExpandEnvironmentStringsW()...
std::stringstream ss;
for (std::wstring::iterator iter = env.begin(); iter != env.end(); ++iter)
{
if (*iter <= 127)
ss << (char) *iter;
else
ss << "\\u" << std::hex << std::setfill('0') << std::setw(4) << (int)*iter;
}
std::string str = ss.str();
// use str as needed...
First convert it from char array to wchar_t array, using the system-default code page.
Then write trivial code that walks over your wchar_t array and escapes every Unicode character with code >= 128.
P.S. Better yet, make your application Unicode so it will use Unicode version of ExpandEnvironmentStrings. This way you will only have to escape the string, plus your app will still work correctly if some environmental string contains a character that doesn’t fit in char with your system-default code page.
Try this code:
string yourAsciiString = "this is test";
string yourUnicodeString = System.Text.Encoding.Unicode.GetString(System.Text.Encoding.ASCII.GetBytes(yourAsciiString));

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.