Preferred conversion from char (not char*) to std::string
Solution 1
std::string
has a constructor that takes a number and a character. The character will repeat for the given number of times. Thus, you should use:
std::string str(1, ch);
Solution 2
To add to the answer, you can simply use initializer list
std::string str = {ch};
Solution 3
just use the overload that takes a char?
i.e. string(1, 'A')
Solution 4
You still can use the string constructor taking two iterators:
char c = 'x';
std::string(&c, &c + 1);
Update:
Good question James and GMan. Just searched freely downloadable "The New C Standard" by Derek M. Jones for "pointer past" and my first hit was:
If the expression P points to an element of an array object and the expression Q points to the last element of the same array object, the pointer expression Q+1 compares greater than P... even though Q+1 does not point to an element of the array object...
On segmented architectures incrementing a pointer past the end of a segment causes the address to wrap segmented architecture around to the beginning of that segment (usually address zero). If an array is allocated within such a segment, either the implementation must ensure that there is room after the array for there to be a one past the end address, or it uses some other implementation technique to handle this case (e.g., if the segment used is part of a pointer’s representation, a special one past the end segment value might be assigned)...
The C relational operator model enables pointers to objects to be treated in the same way as indexes into array objects. Relational comparisons between indexes into two different array objects (that are not both subobjects of a larger object) rarely have any meaning and the standard does not define such support for pointers. Some applications do need to make use of information on the relative locations of different objects in storage. However, this usage was not considered to be of sufficient general utility for the Committee to specify a model defining the behavior...
Most implementations perform no checks prior to any operation on values having pointer type. Most processors use the same instructions for performing relational comparisons involving pointer types as they use for arithmetic types. For processors that use a segmented memory architecture, a pointer value is often represented using two components, a segment number and an offset within that segment. A consequence of this representation is that there are many benefits in allocating storage for objects such that it fits within a single segment (i.e., storage for an object does not span a segment boundary). One benefit is an optimization involving the generated machine code for some of the relational operators, which only needs to check the segment offset component. This can lead to the situation where p >= q is false but p > q is true, when p and q point to different objects.
Solution 5
This works on gcc C++ 4.9.2 (http://ideone.com/f3qhTe)
#include <iostream>
using namespace std;
int main() {
// your code goes here
std::string test;
test = (char) 76;
test += (char) 77;
test += (char) 78;
test += (char) 79;
std::cout << "test contains: " << test << std::endl;
return 0;
}
pythonic metaphor
Updated on January 30, 2022Comments
-
pythonic metaphor about 2 years
I have a
char
, a plain old character, that I would like to turn into anstd::string
.std::string(char)
doesn't exist of course. I could create an char array and copy it in, I could go through string streams, or many other little roundabout routes. Currently, I preferboost::lexical_cast
, but even that seems too verbose for this simple task. So what's the preferred way? -
James McNellis about 13 yearsIs this strictly valid? Can you treat a scalar object as a one-element array and then use the one-past-the-end pointer?
-
Drew Delano about 13 yearsThis is the right answer. But what I don't like about this constructor is that I don't use it enough to remember the order of the parameters. And if you get them switched, it still compiles.
-
pythonic metaphor about 13 years@Fred Larson This is of course what just happened to me as I was trying this solution.
-
Maxim Egorushkin about 13 yearsAbsolutely. An array of one element and a scalar have the same layout and alignment. In fact, sizeof(element) is defined as a multiple of element's alignment, so that there is no padding between the elements of an array.
-
Maxim Egorushkin about 13 yearsIt only works for the case of one char though. What if you have
char x[] = { 'a', 'b', 'c' }
? ) -
GManNickG about 13 years@Maxim: How do we know that? A pointer one past the end of an array is valid (though cannot be dereferenced), but I don't think a pointer one past an element is, like @James says.
-
Rob Kennedy about 13 yearsFor an array of chars, @Maxim, use the constructor that takes a pointer and the number of chars. In your case,
std::string(x, 3)
. -
Maxim Egorushkin about 13 years@GMan: we know it because it is common knowledge. Why could not be an object treated like a one element array?
-
Maxim Egorushkin about 13 years@Rob: but that is another constructor, I was referring to the limitation of the fill constructor. You could do as well
std::string(&ch, 1)
. -
GManNickG about 13 years@Maxim: An appeal to common knowledge is the same as "because I think so, I hope so, and it should be"; that doesn't make it so. No, it's not "common knowledge" or James and I wouldn't be asking. I really doubt that this answer has defined behavior.
-
Cheers and hth. - Alf about 13 years§5.7/4 "For the purposes of these operators, a pointer to a nonarray object behaves the same as a pointer to the first element of an array of length one" It's OK.
-
Rob Kennedy about 13 yearsWell, yeah, @Maxim. The class provides multiple constructors. My point is that we should use the right one for the job.
-
Fred Nurk about 13 years@Fred: std::string is an implementation kitchen-sink all around; however, it helps to remember that all sequences have a constructor taking a count and value parameter, with the value defaulted to T().
-
GManNickG about 13 years@Alf: Thank you, that's more like it.
-
Jonny almost 8 yearsHorrible order of parameters. And why not just allow one char and no count parameter?
-
John H. over 3 yearsLack of char constructor also means lack of conversion. So, e.g., while you can pass a
char*
to a function that takesconst std::string
argument, you can't pass achar
-- which seems unnecessarily limiting. -
John H. over 3 yearsDang I meant
const std::string&
. -
Artur Opalinski over 2 years@MaximEgorushkin Your first sentence should rather read: "You still can use the string constructor taking two pointers:"