Is there an easy STL way to convert a std::string to a std::u32string, i.e. a basic_string of char to char32_t?
This is not a Unicode question.
To initialise a new string:
std::u32string s32(s.begin(), s.end());
To assign to an existing string:
s32.assign(s.begin(), s.end());
If the string might contain characters outside the supported range of char, then this might cause sign-extension issues, converting negative values into large positive values. Dealing with that possibility is messier; you'll have to convert to unsigned char before widening the value.
s32.resize(s.size());
std::transform(s.begin(), s.end(), s32.begin(),
[](char c) -> unsigned char {return c;});
or a plain loop
s32.clear(); // if not already empty
for (unsigned char c : s) {s32 += c;}
s32.resize(s.length());
std::copy(s.begin(),s.end(),s32.begin());
Related
How to use char sumbols from GLSL? Test on https://www.shadertoy.com/new .
int c = int('a'); // Not work
How to get one sumbol or string? For call function.
DrawString("Hello world!"); // Example
I can do this, but it's so hard:
#define _H 72
DrawString(_H, _e, _l, _l, _o);
String and character literals do not exist in GLSL. You can make integer arrays, where the array values represent characters of some kind, but that's about it.
When I try to implement a template to compare two variables' value.
When I try passing string as parameters then the program couldn't compare the value right.
However when I add two same variables this code get me a right result.
Just as the picture shows.
You passed it a const char * pointer to compare and that will compare the pointer addresses, not the contents with '>'. As these are from different objects/strings, you have no way to know which will be first or last in memory, and it may vary from compile to compile, or even potentially run to run.
As you had the std::string local variable, I assume you intended to pass that, which does have comparison operators to compare the contents. If you want to pass a string literal as an std::string to such a template function, you must do it explicitly, such as:
Max<std::string>("a", "b"); // K is std::string, so both parameters will use the implicit constructor
Max(std::string("a"), std::string("b")); // Explicitly construct strings
If you do want Max to work with char pointers, you might overload or specialise it to use say strcmp, which does compare the contents.
template<class T> T Max(T x, T y)
{
return x > y ? x : y;
}
template<> const char* Max(const char *x, const char *y)
{
return strcmp(x, y) > 0 ? x : y;
}
template<> char* Max(char *x, char *y)
{
return strcmp(x, y) > 0 ? x : y;
}
I was trying to create a std::array of char array so that I could declare it static constexpr.
eg:
#include <array>
int main(){
static constexpr char A[] = "abc";
static constexpr char B[] = "def";
static constexpr std::array<char[], 3> tmp{A, B};
}
When I do this I get error message " too many initializers for"
By output of your compiler I could surmise that you have a non-standard extension active. Stricly ISO-wise use of char[] as parameter of template is not legal,. Some compilers would treat that as char[0].
what your array meant to store? way you're trying to do it would store adresses of array to char (and only way to do so would be replace char[] by by const char* in template parameters. std::array is trivial class which stores data statically so you cannot implement array with variable length of strings that way.
Either 1) abolish constexpr and use std::string 2) use const char* 3) worst case (which sometimes is the best) - use fixed array length or "naked" 2-dimensional array with aggregate initializer list.
You may use:
static constexpr std::array<char[4], 2> tmp {{{ A[0], A[1], A[2], A[3] },
{ B[0], B[1], B[2], B[3] }}};
or
static constexpr std::array<char[4], 2> tmp { "abc", "def" };
From http://en.cppreference.com/w/cpp/container/array:
When initializing an object of array type, the initializer must be either a string literal (optionally enclosed in braces) or be a brace-enclosed list of initialized for array members.
Thus you cannot initialize an array (member of std::array of char[4]) by an object of another array.
With C++20 std::to_array can be used.
static constexpr char A[] = "abc";
static constexpr char B[] = "def";
static constexpr auto tmp = std::to_array({A, B});
// this is a substraction example
int x=3098;
int z=3088;
int somme=x-z;
char buffer[4];
// convert int to char
itoa(somme,buffer,10);
// I want to push the buffer value on a char table like this "**0010**" not
// like "**10**"
Then you have to use a formater, standard ones in C are of printf family. Take care of the length of the array because if you want to store a string of length n you need an array of length n+1 (c-strings are Null-terminated). Thus:
// this is a substraction example
int x=3098;
int z=3088;
int somme=x-z;
char buffer[5];
sprintf(buffer,"%04d",somme);
will fit your needs. It means to format the integer somme as (%04d) decimal representation of length 4 padded with leading zeros if needed, and to store the result in memory starting at the beginning of buffer.
I've read in a book:
..characters are just 16-bit unsigned integers under the hood. That means you can assign a number literal, assuming it will fit into the unsigned 16-bit range (65535 or less).
It gives me the impression that I can assign integers to characters as long as it's within the 16-bit range.
But how come I can do this:
char c = (char) 80000; //80000 is beyond 65535.
I'm aware the cast did the magic. But what exactly happened behind the scenes?
Looks like it's using the int value mod 65536. The following code:
int i = 97 + 65536;
char c = (char)i;
System.out.println(c);
System.out.println(i % 65536);
char d = 'a';
int n = (int)d;
System.out.println(n);
Prints out 'a' and then '97' twice (a is char 97 in ascii).