Character Pointer and string variable - c++

I tried to use a character Pointer go throw string character (iterate) but I found i can not say the below:
string Name = "Hello";
char *ch = Name;
like the previous statements i am getting error during execution.
However when I am doing like that:
char *ch = "Hello";
the program running without throwing any exception.
Why is that?

I have recently encountered similar problem and the simplest answer is that std::string is a different type from char*, more precisely std::string is an object which contains some characters (your text) and few methods, which allow you to do multiple operations with your text. You can imagine creating a class Integer for storing the value, but also a method allowing you to square and cube the number which is stored in the Ingerer class. Even though they could store the same numerical value, you will not be able to compare them (unless you overload the operator==), as their types are different.
If you wish to use the code you provided, you need to rewrite the second line as
const char *ch = Name.c_str();
it is allowed because std::string contains a method c_str() which "casts" itself to const char*. If you want to learn more about strings, be sure to visit C++ reference about strings.

Related

C++ How to populate a static array of strings with new strings in different locations?

Say I got this
char* MapIds[5000] = { "Northeast Asia","Hanyang","Pusan","Pyongyang","Shanghai","Beijing","Hong Kong", /*...5000 values etc../* };
I tried
strcpy(MapIds[0], "gfggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg");
But it crashes
How Do I keep changing them around without messing up the strings in other elements.
I dont want to use std::string or vector those cause crazy slow compile times.
Because you try to copy into a literal string ("Northeast Asia").
In C++ a literal string is really a constant array of characters, any attempt to modify such an array will lead to undefined behavior (which can sometimes express themselves as crashes).
If you want to make MapIds[0] point to a new string, then you simply use assignment:
MapIds[0] = "gfggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg";
Because literal strings are constant arrays of characters, C++ doesn't really allow you to have a char* to point to them, you must use const char*:
const char* MapIds[] = { ... };
However, a much better solution is to not use C-style strings and char pointers (const or not) at all, but only use std::string:
std::string MapIds[] = { ... };
Then you can modify the strings in the array itself, using plain assignment as shown above.

conversion between char* and std::string and const char*

I am now using C++ to program a robot using PROS. Pros has a print function, which is taking in a const char*. Now, I'm using lvgl to create my own screen, and I want to replicate the print function. Like the printf() functions, I want it to include variadic params to do the %d effect (so it converts all the %? to the corresponding values). The problem now is about the conversions between functions. I wanted to make a convert function to convert a string and the variadic params into a complete string. I need to input is a string which is like "hey" and I'm unsure what the type name should be. I need to be able to get size, search in it for %ds but I need the function to return a const char* to pass onto the lvgl to pring on the screen. I am having a bad time trying to convert a string into an const char* for the out put of the convert function.
Also, I tried using the input type as a char*, and when I input a string like "hello" is says a error [ISO C++11 does not allow conversion from string literal to 'char ' [-Wwritable-strings]]. But instead, when is use a const char, the error disappears. Anyone knows why?
Thanks everyone for your kind help!
char* and const char* are two flavours of the same thing: C-style strings. These are a series of bytes with a NUL terminator (0-byte). To use these you need to use the C library functions like strdup, strlen and so on. These must be used very carefully as missing out on the terminator, which is all too easy to do by accident, can result in huge problems in the form of buffer-overflow bugs.
std::string is how strings are represented in C++. They're a lot more capable, they can support "wide" characters, or variable length character sets like UTF-8. As there's no NUL terminator in these, they can't be overflowed and are really quite safe to use. Memory allocation is handled by the Standard Library without you having to pay much attention to it.
You can convert back and forth as necessary, but it's usually best to stick to std::string inside of C++ as much as you can.
To convert from C++ to C:
std::string cppstring("test");
const char* c_string = cppstring.c_str();
To convert from C to C++:
const char* c_string = "test";
std::string cppstring(c_string);
Note you can convert from char* (mutable) to const char* (immutable) but not in reverse. Sometimes things are flagged const because you're not allowed to change them, or that changing them would cause huge problems.
You don't really have to "convert" though, you just use char* as you would const char*.
std::string A = "hello"; //< assignment from char* to string
const char* const B = A.c_str(); //< call c_str() method to access the C string
std::string C = B; //< assignment works just fine (with allocation though!)
printf("%s", C.c_str()); //< pass to printf via %s & c_str() method

How do I call char constructor instead of char[] constructor

My school project asks me to re-create the std::string class (with less detail). I'm having a small problem that I have two conflicting(?) constructors.
The problem is when I want to create a String from a single character. Instead of calling
String(char);
it calls
String(char[]);
How can I specify which constructor I would like called?
Update
Wow, now I feel silly. I was calling using char* and not a char so of course it would call the array/pointer version. Thanks for making this painfully obvious to me :)
Supposed you have the following
class String {
public:
String(char);
String(char[]);
};
you'll use
char charvar = 'X';
String s(charvar);
to call the 1st form, and
char strvar[] = "XXXX";
String s(strvar);
to call the second.
Beyond this your question is too unclear/unspecific, to give a concise answer for what you actually want to achieve.
You need to use single quotes to specify a char otherwise it will consider it a char[] with a single character (aside from the termination character)
'a' // char
"a" // char[]

Returning a constant char pointer yields an error

I am new to C++, and haven't quite grasped all the concepts yet, so i am perplexed at why this function does not work. I am currently not at home, so i cannot post the compiler error just yet, i will do it as soon as i get home.
Here is the function.
const char * ConvertToChar(std::string input1, std::string input2) {
// Create a string that you want converted
std::stringstream ss;
// Streams the two strings together
ss << input1 << input2;
// outputs it into a string
std::string msg = ss.str();
//Creating the character the string will go in; be sure it is large enough so you don't overflow the array
cont char * cstr[80];
//Copies the string into the char array. Thus allowing it to be used elsewhere.
strcpy(cstr, msg.c_str());
return * cstr;
}
It is made to concatenate and convert two strings together to return a const char *. That is because the function i want to use it with requires a const char pointer to be passed through.
The code returns a pointer to a local (stack) variable. When the caller gets this pointer that local variable doesn't exist any more. This is often called dangling reference.
If you want to convert std::string to a c-style string use std::string::c_str().
So, to concatenate two strings and get a c-style string do:
std::string input1 = ...;
std::string input2 = ...;
// concatenate
std::string s = input1 + input2;
// get a c-style string
char const* cstr = s.c_str();
// cstr becomes invalid when s is changed or destroyed
Without knowing what the error is, it's hard to say, but this
line:
const char* cstr[80];
seems wrong: it creates an array of 80 pointers; when it
implicitly converts to a pointer, the type will be char
const**, which should give an error when it is passed as an
argument to strcpy, and the dereference in the return
statement is the same as if you wrote cstr[0], and returns the
first pointer in the array—since the contents of the array
have never been initialized, this is undefined behavior.
Before you go any further, you have to define what the function
should return—not only its type, but where the pointed to
memory will reside. There are three possible solutions to this:
Use a local static for the buffer:
This solution was
frequently used in early C, and is still present in a number of
functions in the C library. It has two major defects: 1)
successive calls will overwrite the results, so the client code
must make its own copy before calling the function again, and 2)
it isn't thread safe. (The second issue can be avoided by using
thread local storage.) In cases like yours, it also has the
problem that the buffer must be big enough for the data, which
probably requires dynamic allocation, which adds to the
complexity.
Return a pointer to dynamically allocated memory:
This works well in theory, but requires the client code to free
the memory. This must be rigorously documented, and is
extremely error prone.
Require the client code to provide the buffer:
This is probably the best solution in modern code, but it does
mean that you need extra parameters for the address and the
length of the buffer.
In addition to this: there's no need to use std::ostringstream
if all you're doing is concatenating; just add the two strings.
Whatever solution you use, verify that the results will fit.

Want to use atoi() on type char whilst reading a file?

I have extracted the contents of a file mapped into memory, into an array which looks like:
char* const arr = static_cast<char *>(file.get_address());
whilst iterating through the array I wish to be able to call:
for(int i=0; i<file.get_size(); i++){
atoi(arr[i]);
}
however, atoi requires type const char* and arr[i] is type char* const. How may I resolve this?
First of all, I question your use of const in...
char* const arr = static_cast<char *>(file.get_address());
In this case, the const applies to the pointer, not to what it points at. So, via your arr pointer, you could do this...
arr[0] = 'a';
...which I think is not what you're trying to protect against. Instead, I think what you really want is:
const char* arr = static_cast<const char *>(file.get_address());
...which resolves what your question was posted about. In this way, you have a pointer that points to characters that can't be changed (at least not directly through that pointer).
Then, in your loop, you're calling atoi() on each character of the whole file, which I doubt is what you really want to do. Are you expecting a whole bunch of single-digit decimal (base 10) numbers, with no separators? That's the only use case for looping the way you are. For the sake of argument, let's suppose that's what you really want. OK, then, where do you want the results to go? You're not assigning the returned value of atoi() to anything. You're converting the single-digit (presumably ASCII) numbers from text into numeric form, but throwing away the results.
But I think that's probably not what you really want anyway.
Let's rewrite your code so that it will convert the file's first textual value (assuming it's not preceded by garbage) into an integer, and then print it. As in your example, we'll assume the file is already read into some object named file and that we can get its data buffer by calling file.get_address(). Here's what you'd want:
const char* arr = static_cast<const char *>(file.get_address());
int firstNumericValue = atoi(arr);
std::cout << "firstNumericValue = " << firstNumericValue << "\n";
...and that's all, no looping required! If you want to read in multiple values from the file, of course you could use looping, but you'll want to look into more advanced functions, such as sscanf() or strtol(). If you use strtol(), its second argument lets you get a pointer to the next place to begin converting for any subsequent calls. But examples for these abound, and you can research them yourself.
atoi(&(arr[i]));
will do the trick.
The & operator gives you a pointer to the char and the extra parentheses ensure that you are getting a pointer to the i-th element.
atoi doesn't care about the const on the array declaration, so it isn't relevant here.