how can i assign float value to char* c[] array - c++

I have string,int,float values and trying to assign those values to char* c[] array like this.
char *str = "helloo";
int int = 1000;
short st1[]={32760};
float flt = 2.345;
char* c [] = {(char*)int1,(char*)str,(char*)flt,(char*)st1};
but for float getting illegal explicit conversion from 'float' to 'char * '
anybody tel me how to assign?

You can't just cast those types and expect to get useful results. Casting is a minimal operation which can work to transform data in certain predefined ways, but it won't (for example) intelligently turn integers into their string representations.
That's why your compiler is complaining.
If you want the string representation of numeric data, you have to convert them differently, with something like:
char intStr[30]
sprintf (intStr, "%d", int1);
If you're looking to get string representations of them all, you can do something like:
char *str = "helloo";
int int1 = 1000;
short st1[]={32760};
float flt = 2.345;
char mybuff1[50], mybuff2[50], mybuff3[50], mybuff4[50];
sprintf (mybuff1, "%d", int1);
sprintf (mybuff2, "%s", str);
sprintf (mybuff3, "%f", flt);
sprintf (mybuff4, "%d", st1[0]);
char *c [] = {mybuff1, mybuff2, mybuff3, mybuff4);
And be aware that, although C and C++ have very similar idioms, and are mostly compatible if you stick to a subset, they are not the same language and the best way to do something changes dramatically depending on the actual language you're using.
For example, it's rarely necessary to use C-style strings in C++ since that language provides an impressive real string type. Ditto for malloc/free as opposed to new/delete and many other aspects.
Questions should generally be tagged C or C++, rarely both.

In C++:
#include <string>
std::string arr[] = { std::to_string(1000),
"helloo",
std::to_string(2.345f),
std::to_string(32760) };
You can use arr[0].c_str() etc. to get back char const *s.

Related

how character pointer could be used to point a string in c++?

First of all I am beginner in C++. I was trying to learn about type casting in C++ with strings and character pointer. Is it possible to point a string with a character pointer?
int main() {
string data="LetsTry";
cout<<(&data)<<"\n";
cout<<data<<"\n"<<"size "<<sizeof(data)<<"\n";
//char *ptr = static_cast<char*>(data);
//char *ptr=(char*)data;
char *ptr = reinterpret_cast<char*>(&data);
cout<<(ptr)<<"\n";
cout<<*ptr;
}
The above code yields outcome as below:
0x7ffea4a06150
LetsTry
size 32
`a���
`
I understand as ptr should output the address 0x7ffea4a06150
Historically, in C language strings were just a memory areas filled with characters. Consequently, when a string was passed to a function, it was passed as a pointer to its very first character, of type char *, for mutable strings, or char const *, if the function had no intent to modify string's contents. Such strings were delimited with a zero-character ((char)0 a.k.a. '\0') at the end, so for a string of length 3 you had to allocate at least four bytes of memory (three characters of the string itself plus the zero terminator); and if you only had a pointer to a string's start, to know the size of the string you'd have to iterate it to find how far is the zero-char (the standard function strlen did it). Some standard functions accepted en extra parameter for a string size if you knew it in advance (those starting with strn or, more primitive and effective, those starting with mem), others did not. To concatenate two strings you first had to allocate a sufficient buffer to contain the result etc.
The standard functions that process char pointers can still be found in STL, under the <cstring> header: https://en.cppreference.com/w/cpp/header/cstring, and std::string has synonymous methods c_str() and data() that return char pointers to its contents, should you need it.
When you write a program in C++, its main function has the header of int main(int argc, char *argv[]), where argv is the array of char pointers that contains any command-line arguments your program was run with.
Ineffective as it is, this scheme could still be regarded as an advantage over strings of limited capacity or plain fixed-size character arrays, for instance in mid-nineties, when Borland introduced the PChar type in Turbo Pascal and added a unit that exported Pascal implementations of functions from C's string.h.
std::string and const char* are different types, reinterpret_cast<char*>(&data) means reinterpret the bits located at &data as const char*, which is not we want in this case.
so assuming we have type A and type B:
A a;
B b;
the following are conversion:
a = (A)b; //c sytle
// and
a = A(b);
// and
a = static_cast<A>(b); //c++ style
the following are bit reinterpretation:
a = *(A*)&b; //c style
// and
a = *reinterpret_cast<A*>(&b); //c++ style
finally, this should works:
int main() {
string data = "LetsTry";
const char *ptr = data.c_str();
cout<< ptr << "\n";
}
bit reinterpretation is sometimes used, like when doing bit manipulation of a floating point number, but there are some rules to follow like this one What is the strict aliasing rule?
also note that cout << ptr << "\n"; is a specially case because feeds a pointer to std::cout usually output the address that pointer points to, but std::cout treats char* specially so that it output the content of that char array instead
In C++, string is class and what you doing is creating a string object. So, to use are char * you need to convert it using c_str()
You can refer below code:
std::string data = "LetsTry";
// declaring character array
char * cstr = new char [data.length()+1];
// copying the contents of the
// string to char array
std::strcpy (cstr, data.c_str());
Now, you can get use char * to point your data.

Issues with converting between "string" "const unsigned char" and "utf8proc_uint8_t"

Maybe a simple issue, but I've gotten confused between "byte arrays", pointers and casts in c++.
Take a look at the following and let me know what I need to read about to fix it, as well as the fix. It relates to the utf8proc library.
const unsigned char *aa = (const unsigned char*)e.c_str();
utf8proc_uint8_t* a = utf8proc_NFC(aa);
char b = (char)a;
string d = string(b);
It is bad enough no need for an error message here, but there is no constructor string on the string(b) line.
There appear to be a couple problems here. The biggest is the assignment:
char b = (char)a;
What you are doing is telling the compiler to take the pointer (memory location) and convert that to a char, then assign it to single char value b. So you'll basically have random jibberish in b.
Instead, if you want to treat a like a basic char*, you would write:
char* b = (char*)a;
Then you could use the string class with either:
string d = string(b);
or you could skip several line by the direct conversion:
string d = string((char*)a);
You are also looking for a headache down the line if you don't delete the conversion value returned by the utf8proc_NFC() call, and if you don't do an error check after the conversion.
Plus I'll put in a plug for using some Hungarian notation to distinguish a pointer (a 'p' prefix on variables). This makes it obvious that you can do things like:
char tmp = *pStr; // a single character (first in the string)
char tmp2 = pStr[1]; // a single character (second in the string)
char* pTmp = pStr; // a pointer to a null terminated string
But you would never see:
char tmp3 = (char)pStr; // compiles, but makes no sense to treat pointer as a character.
So here is a clean version of all of this:
utf8proc_uint8_t* pUTF = utf8proc_NFC( (const unsigned char*)e.c_str() );
string strUTF;
if (pUTF)
{
strUTF = (char*)pUTF;
free pUTF;
}
This code is almost certainly not what you want, since it is casting a pointer into a scalar.
utf8proc_uint8_t* a = ...;
char b = (char)a;
Instead, you want to cast and produce a pointer:
utf8proc_uint8_t* a = ...;
const char *b = (const char *)a;
I also added const, which is not strictly necessary but a good idea to use wherever you can.

Making a std::string out of a Char* in C++

OSX 10.8, Carbon
I have a std::string that I want to derive from a Char*
Example:
CFStringRef *s;
char *c[128];
CFStringGetCString(*s, *c, 128, kCFStringEncodingUTF8);
int size = sizeof(c);
g_uid.assign(c, size);
But I am getting an invalid conversion and I dont understand why
error: invalid conversion from 'char**' to 'long unsigned int'
std::string g_uid = ""; is defined as a global
You're too generous with the asterisks - you generally don't need a pointer to CFStringRef, and your array is actually an array of pointers, which is not what you want.
It should look more like this:
CFStringRef s;
char c[128];
if (CFStringGetCString(s, c, 128, kCFStringEncodingUTF8))
{
g_uid = c;
}
else
{
// 128 characters wasn't enough.
}
If c where a char*, the following would work:
g_uid.assign(c, size);
The problem is that c isn't char*, it's an array of 128 char*s:
char *c[128];
This is a common beginners mistake in C/C++. I remember making this same mistake back in the day. A declaration like
char *c[128]; isn't giving you an array of 128 characters as you might be led to believe. Its actually giving you an array of 128 pointers to chars. You don't want that.
You want to declare an array of 128 chars which looks like:
char c[128];
Now you might not think that c was a char* because you don't see any *s but any time you declare an array of something, that variable is automatically a pointer of whatever type you specify. It actually points to the address of the very first element of the array.

connecting chars*

How would I connect to char* strings to each other.
For example:
char* a="Heli";
char* b="copter";
How would I connect them to one char c which should be equal to "Helicopter" ?
strncat
Or use strings.
size_t newlen = strlen(a) + strlen(b);
char *r = malloc(newlen + 1);
strcpy(r, a);
strcat(r, b);
In C++:
std::string foo(a);
std::string bar(b);
std::string result = foo+bar;
If your system has asprintf() (pretty common these days), then it's easy:
char* p;
int num_chars = asprintf(&p, "%s%s", a, b);
The second argument is a format string akin to printf(), so you can mix in constant text, ints, doubles etc., controlling field widths and precision, padding characters, justification etc.. If num_chars != -1 (an error), then p then points to heap-allocated memory that can be released with free(). Using asprintf() avoids the relatively verbose and error-prone steps to calculate the required buffer size yourself.
In C++:
std::string result = std::string(a) + b;
Note: a + b adds two pointers - not what you want, hence at least one side of the + operator needs to see a std::string, which will ensure the string-specific concatenation operator is used.
(The accepted answer of strncat is worth further comment: it can be used to concatenate more textual data after an ASCIIZ string in an existing, writeable buffer, in-so-much as that buffer has space to spare. You can't safely/portably concatenate onto a string literal, and it's still a pain to create such a buffer. If you do it using malloc() to ensure it's exactly the right length, then strcat() can be used in preference to strncat() anyway.)

What can you use to cast an int/float to a wchar_t*?

If you have an int or float, how can you cast it to a wchar_t* without using external libraries like boost?
std::wostringstream oss;
int i = 1212; // or float f = 1212.0f;
oss<<i; // oss<<f;
std::wstring ws = oss.str();
const wchar_t* cwp = ws.c_str(); // const wchar_t*
std::vector<wchar_t> buf( cwp , cwp + (wc.size() + 1) );
wchar_t* wp = &buf[0]; // wchar_t*
You can't cast it meaningfully:
int x = 43;
wchar_t *ptr = reinterpret_cast<wchar_t *>(x);
This will compile, but it has no meaning. It simply re-interprets the integer value and forces the creation of a pointer with that value. Since there is nothing valid for you access at the address, it is meaningless and useless.
If you mean "convert", there is probably a wide-character version of snprintf() you can use, e.g. snwprintf() or similar. This might depend a bit on your platform.
It's not exactly casting, but I suspect you want to have a string representation. printf-family functions or stringstreams may be of help. Why would you want to cast it to wchar_t is beyond me.
You can do it this way, in conjunction to hacker's answer above
int num1 = 25;
float fnum1 = 3.14;
char buf[50];
sprintf(buf, "Int: %d. Float: %4.2f", num1, fnum1);
The only thing you have to be careful is to ensure you have enough sufficient space in the buffer for the sprintf function to work, otherwise you will get an overflow and corrupt another area of memory which will crash your program.
Hope this helps,
Best regards,
Tom.