Does `std::string` Store its Characters Internally as Signed Chars? [duplicate] - c++

This question already has answers here:
Difference between char and signed char in c++?
(4 answers)
Closed 4 years ago.
I'm writing an algorithm requires me to insert values into the std::string via an unsigned 1 byte integer (0 - 255) and calls for me to print the values of the individual characters of the string as integers, however, I keep getting negative values. My wild guess is that the characters are stored in the std::string as signed 1 byte characters (-128 to 127), hence, why I'm getting negative values for output. The negative values are the equivalent negative forms of the positive values I'm inserting. I did a bit of research, but couldn't seem to find a way to word my question in a way that produced the answer I was looking for.

No, this is implementation-dependent.
std::string is an alias for std::basic_string<char>, so the question boils down to the signedness of char on your plarform/implementation.
If you want it unsigned, explicitly convert it:
std::cout << static_cast<int>(static_cast<unsigned char>(ch));
Or alternatively, as suggested in comments, use vector<uint8_t> instead of string.

This has nothing really to do with string, it's just that char may be a signed type. All you need to do is cast your char to unsigned char. E.g.
char some_char = ...;
cout << (int)(unsigned char)some_char;
or
string some_string = ...;
cout << (int)(unsigned char)some_string[0];

Related

Generating a char using input from user in C++ [duplicate]

This question already has answers here:
How to convert a std::string to const char* or char*
(11 answers)
Closed 7 years ago.
I wish to make a char with digits between 0-9. The user decides how many digits to use.
For example, if the user inputs 4, the char should be 01234.
Please note I cannot use the string data type. I have to use char.
I know how to generate a string for the same logic but not a char.
So if there is a way to convert string to char, that will work well. I tried
string randomString; //this contains the set of numbers 0-9 on the basis of the users input
char charString = randomString;
This however does not work.
So if there is a way to convert string to char
Yes, it's called a character array and you can easily convert a string type to a character array like so:
const char* charString = randomString.c_str();
You can find more information about c_str() method here and you should review this material regarding character arrays.
If you require a non-const (can be modified) character array, refer to the above links which will explain it and actually give examples about how to accomplish that.

C++ Decimal to Hexadecimal (int to char)

I'm trying to make a function that takes an int in as a parameter and returns a hexadecimal of type char. Here is the function:
char toHex(int dec)
{
std::stringstream a;
a << std::hex << dec;
return a.str().c_str()[0];
}
It returns the hexidecimal version, but only the first digit, as I wrote the [0]. So if the hex value is 14 then I only get a 1. Without this [] specification, it is an std::string, but I need the complete hexadecimal in char form.
I was thinking about making a for loop that replaces the 0 with a cycle so that it iterates through the first i characters, but I don't think there is a way to append regular characters (char) together. What should I do? Thanks!
Edit:
To be clear, I want to do this process as an example:
declare a char variable, char h, then convert the integer 104 to hex, which is 0x68, then assign 0x68 to the variable h of type char
A character can only hold... well, one character. 0-F would be one character in the case of a hex number. When you have an array of characters (multiple characters), you have a string. How could you possibly represent the decimal number 255, hex FF as a single character?
A char can only represent a single character. If you need the whole string, the best thing to do would be to return the std::string created by the call to a.str().
If you need to return a C-style string, then you need to return a char * (or char const *) that points to the storage location for the characters, at which point you need to manage its lifetime (which std::string does for you).

c++ convert a word with 4 character stored as char* to an int and vice versa [duplicate]

This question already has answers here:
Using bitwise operators in C++ to change 4 chars to int
(2 answers)
Closed 8 years ago.
I'm searching for a way to convert a word with 4 characters stored as char* to an int and vice versa because i want to transfer the char* through a function which needs an int as argument. Here's an example:
char* word = "abcd";
int number;
// write word in number
char* word2;
// write number in word2
At the end word2 should be the same as word. It would also help me if you know how to convert it in one direction only.
Assuming it will be converted back on a system with the same endianness
number=*((int*)word);
Convert back:
char word2[5];
*((int*)word2) = number;
word2[4]=0;

Char array to long to char array [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Converting a four character string to a long
I want to convert a char array to a long and back again but I'm a bit stuck.
This is a fragment of the code I've got so far:
char mychararray[4] = {'a', 'b', 'c', 'd'};
unsigned long * mylong = (unsigned long *)&mychararray;
cout << *mylong << endl;
Which should take the char array, and represent the first 4 bytes (the length of a long) as a long (I think).
Is this correct? And how would I undo it to get the char array back?
Thanks for your help.
EDIT: The third line was a typo - *mychararray should have been *mylong
You're assuming sizeof(long) == 4, which can be wrong. (Especially on 64 bit platforms). If that assumption is broken, you're in undefined behavior territory: manipulating mylong will read/write beyond mychararray's allocated memory.
Your second line has no effect if you don't use *mylong on the third line
You can get back a char* with something like:
char *thing = reinterpret_cast<char*>(mylong);
(You should be using that type of cast in the first case also, it's more explicit than the C-type cast.)
Another thing to watch out for is the endianess of the CPU if multiple machines are involved. You'll end up with the chars reversed if they are different.
Yes, it should conceptually work. Such casts however make assumptions about the underlying platform. If, you are however using C++, I would suggest that you use a C++ typecast.
reinterpret_cast is specifically for your case.

How to convert char* to unsigned short in C++

I have a char* name which is a string representation of the short I want, such as "15" and need to output this as unsigned short unitId to a binary file. This cast must also be cross-platform compatible.
Is this the correct cast: unitId = unsigned short(temp);
Please note that I am at an beginner level in understanding binary.
I assume that your char* name contains a string representation of the short that you want, i.e. "15".
Do not cast a char* directly to a non-pointer type. Casts in C don't actually change the data at all (with a few exceptions)--they just inform the compiler that you want to treat one type into another type. If you cast a char* to an unsigned short, you'll be taking the value of the pointer (which has nothing to do with the contents), chopping off everything that doesn't fit into a short, and then throwing away the rest. This is absolutely not what you want.
Instead use the std::strtoul function, which parses a string and gives you back the equivalent number:
unsigned short number = (unsigned short) strtoul(name, NULL, 0);
(You still need to use a cast, because strtoul returns an unsigned long. This cast is between two different integer types, however, and so is valid. The worst that can happen is that the number inside name is too big to fit into a short--a situation that you can check for elsewhere.)
#include <boost/lexical_cast.hpp>
unitId = boost::lexical_cast<unsigned short>(temp);
To convert a string to binary in C++ you can use stringstream.
#include <sstream>
. . .
int somefunction()
{
unsigned short num;
char *name = "123";
std::stringstream ss(name);
ss >> num;
if (ss.fail() == false)
{
// You can write out the binary value of num. Since you mention
// cross platform in your question, be sure to enforce a byte order.
}
}
that cast will give you (a truncated) integer version of the pointer, assuming temp is also a char*. This is almost certainly not what you want (and the syntax is wrong too).
Take a look at the function atoi, it may be what you need, e.g. unitId = (unsigned short)(atoi(temp));
Note that this assumes that (a) temp is pointing to a string of digits and (b) the digits represent a number that can fit into an unsigned short
Is the pointer name the id, or the string of chars pointed to by name? That is if name contains "1234", do you need to output 1234 to the file? I will assume this is the case, since the other case, which you would do with unitId = unsigned short(name), is certainly wrong.
What you want then is the strtoul() function.
char * endp
unitId = (unsigned short)strtoul(name, &endp, 0);
if (endp == name) {
/* The conversion failed. The string pointed to by name does not look like a number. */
}
Be careful about writing binary values to a file; the result of doing the obvious thing may work now but will likely not be portable.
If you have a string (char* in C) representation of a number you must use the appropriate function to convert that string to the numeric value it represents.
There are several functions for doing this. They are documented here:
http://www.cplusplus.com/reference/clibrary/cstdlib