Printing out a map, cannot convert const string to const char array - c++

I need to loop through the map, and send a const char array to the function to print it, I tried to use string cpy but the result is the same, it cannot convert a const string to a char. What am i doint wrong?
std::map <std::string, int>::const_iterator end = scores.end();
std::map<std::string, int>::const_iterator it;
for (it = scores.begin(); it != end; ++it)
{
char initials[4];
strcpy(initials,it->first);
//std::string s = "";
DrawString(screen, widthscreen/2 - (14*16)/4, heightscreen/2, initials,charsetsmall, 8);

You need to use string member function string::c_str
it->first returns std::string not underlying character data. To extract that you need to use the above member function.
You should use:
strcpy(initials,it->first.c_str());

Use the c_str() member of std::string.
DrawString(..., it->first.c_str(), ...);

strcpy(initials,it->first); //error
It should be this:
strcpy(initials,it->first.c_str()); //ok
Because first is std::string. You need to get the const char* which std::string stores by calling c_str().
By the way, are you sure the maxium size of the string would be 4 including the null-character? Better use strncpy instead of strcpy as:
strncpy(initials,it->first.c_str(), 4); //better
The third argument is the number of characters to be copied from source to destination.

you have to convert string to char. Try
it->first.c_str();

strcpy(initials,it->first);
change it to
strcpy(initials, it->first.c_str());
But this may generate some security issues.

Related

How am I able to iterate through a string vector in c++?

I want to iterate through a string vector in c++. I want to open each item in the list with fopen.
const char *filep //fopen needs a constant char pointer.
for (vector<string>::iterator it = filelist.begin(); it != filelist.end(); it++)
{
filep = (const char *)it; //This isn't working. How can I fix this
fopen(filep, "rb");
}
You should have used it->c_str() as it is essentially a pointer to the element in the std::vector. But for an easier life use
for (const auto& s : filelist){
// s is a const reference to an element in filelist
// use s.c_str() if you need the character buffer
}
This is valid from C++11 onwards. Using const auto& rather than auto obviates a std::string copy.
Change this:
filep = (const char *)it;
to this:
filep = it->c_str();
However, you do extra, unnecessary steps, since you could just do this instead:
for (vector<string>::iterator it = filelist.begin(); it != filelist.end(); it++)
fopen(it->c_str(), "rb");
which reduces the number of lines of your code to just two, and doesn't use an extra pointer.
PS: A more modern approach can be found in Bathsheba's answer, or use the auto&& approach.
create a method getstring in which you will return the string.
for(unsigned int i=0; i<iterator.size();i++){
cout << iterator[i]->getstring()<<endl;
}
A std::string is a type which is completely different from const char *. Hence, you need to get underlying character buffer stored in string. For that You must use method std::string::c_str() or std::string::data() whatever you like.
Do it like below (Inspired from other answers now using range-based for-loop),
const char *filep //fopen needs a constant char pointer.
for (auto & str : filelist)
{
filep = str.c_str();
fopen(filep, "rb");
}

How can I convert const char* to string and then back to char*?

I'm just starting c++ and am having difficulty understanding const char*. I'm trying to convert the input in the method to string, and then change the strings to add hyphens where I want and ultimately take that string and convert it back to char* to return. So far when I try this it gives me a bus error 10.
char* getHyphen(const char* input){
string vowels [12] = {"A","E","I","O","U","Y","a","e","i","o","u","y"};
//convert char* to string
string a;
int i = 0;
while(input != '\0'){
a += input[i];
input++;
i++;
}
//convert a string to char*
return NULL;
}
A: The std::string class has a constructor that takes a char const*, so you simply create an instance to do your conversion.
B: Instances of std::string have a c_str() member function that returns a char const* that you can use to convert back to char const*.
auto my_cstr = "Hello"; // A
std::string s(my_cstr); // A
// ... modify 's' ...
auto back_to_cstr = s.c_str(); // B
First of all, you don't need all of that code to construct a std::string from the input. You can just use:
string a(input);
As far as returning a new char*, you can use:
return strdup(a.c_str()); // strdup is a non-standard function but it
// can be easily implemented if necessary.
Make sure to deallocate the returned value.
It will be better to just return a std::string so the users of your function don't have to worry about memory allocation/deallocation.
std::string getHyphen(const char* input){
Don't use char*. Use std::string, like all other here are telling you. This will eliminate all such problems.
However, for the sake of completeness and because you want to understand the background, let's analyse what is going on.
while(input != '\0'){
You probably mean:
while(*input != '\0') {
Your code compares the input pointer itself to \0, i.e. it checks for a null-pointer, which is due to the unfortunate automatic conversion from a \0 char. If you tried to compare with, say, 'x' or 'a', then you would get a compilation error instead of runtime crashes.
You want to dereference the pointer via *input to get to the char pointed to.
a += input[i];
input++;
i++;
This will also not work. You increment the input pointer, yet with [i] you advance even further. For example, if input has been incremented three times, then input[3] will be the 7th character of the original array passed into the function, not the 4th one. This eventually results in undefined behaviour when you leave the bounds of the array. Undefined behaviour can also be the "bus error 10" you mention.
Replace with:
a += *input;
input++;
i++;
(Actually, now that i is not used any longer, you can remove it altogether.)
And let me repeat it once again: Do not use char*. Use std::string.
Change your function declaration from
char* getHyphen(const char* input)
to
auto hyphenated( string const& input )
-> string
and avoid all the problems of conversion to char const* and back.
That said, you can construct a std::string from a char_const* as follows:
string( "Blah" )
and you get back a temporary char const* by using the c_str method.
Do note that the result of c_str is only valid as long as the original string instance exists and is not modified. For example, applying c_str to a local string and returning that result, yields Undefined Behavior and is not a good idea. If you absolutely must return a char* or char const*, allocate an array with new and copy the string data over with strcpy, like this: return strcpy( new char[s.length()+1], s.c_str() ), where the +1 is to accomodate a terminating zero-byte.

Convert vector of uint8 to string

I have a pointer to a vector of type uint8.
How would I take this pointer and convert the data in the vector into a full string representative of its content?
You could just initialize the std::string with the sequence obtained from the std::vector<uint8_t>:
std::string str(v->begin(), v->end());
There is no need to play any tricks checking whether the std::vector<uint8_t> is empty: if it is, the range will be empty. However, you might want to check if the pointer is v is null. The above requires that it points to a valid object.
For those who wants the conversion be done after a string is declared, you may use std::string::assign(), e.g.:
std::string str;
std::vector<uint8_t> v;
str.assign(v.begin(), v.end());
vector<uint8_t> *p;
string str(
p && !p->empty() ? &*p->begin() : NULL,
p && !p->empty() ? &*p->begin() + p->size() : NULL);

Get first char from std::string

I need to get the first character of an std::string with a minimum amount of code.
It would be great if it would be possible to get the first char in one line of code, from an STL std::map<std::string, std::string> map_of_strings. Is the following code correct:
map_of_strings["type"][0]
EDIT
Currently, I am trying to use this piece of code. Is this code correct?
if ( !map_of_strings["type"].empty() )
ptr->set_type_nomutex( map_of_strings["type"][0] );
The prototype of the set_type function is:
void set_type_nomutex(const char type);
That should work if you've put a non-empty string into map_of_strings["type"]. Otherwise, you'll get an empty string back, and accessing its contents will probably cause a crash.
If you can't be sure whether the string exists, you can test:
std::string const & type = map["type"];
if (!type.empty()) {
// do something with type[0]
}
Or, if you want to avoid adding an empty string to the map:
std::map<std::string,std::string>::const_iterator found = map.find("type");
if (found != map.end()) {
std::string const & type = found->second;
if (!type.empty()) {
// do something with type[0]
}
}
Or you could use at to do a range check and throw an exception if the string is empty:
char type = map["type"].at(0);
Or in C++11, the map also has a similar at which you can use to avoid inserting an empty string:
char type = map.at("type").at(0);
The c_str() method will return a pointer to the internal data. If the string is empty, then a pointer to a NULL-termination is returned, so a simple one-liner is safe and easy:
std::string s = "Hello";
char c = *s.c_str();
It's not exactly clear from your question what your problem is, but the thing likely to go wrong with map_settings["type"][0] is that the returned string may be empty, resulting in undefined behavior when you do [0]. You have to decide what you want to do if there is no first character. Here's a possibility that works in a single line.
ptr->set_type_nomutex( map_settings["type"].empty() ? '\0' : map_settings["type"][0]);
It gets the first character or a default character.
string s("type");
char c = s.at(0);

How to convert a char* pointer into a C++ string?

I have a C++ string. I need to pass this string to a function accepting a char* parameter (for example - strchr()).
a) How do I get that pointer?
b) Is there some function equivalent to strschr() that works for C++ strings?
To get the C string equivalent of
the C++ string object use c_str
function.
To locate the first occurence of a
char in a string object use
find_first_of function.
Example:
string s = "abc";
// call to strlen expects char *
cout<<strlen(s.c_str()); // prints 3
// on failure find_first_of return string::npos
if(s.find_first_of('a') != string::npos)
cout<<s<<" has an a"<<endl;
else
cout<<s<<" has no a"<<endl;
Note: I gave the strlen just an example of a function that takes char*.
Surprisingly, std:;string has far, far more capabilities than C-style strings. You probably want the find_first_of() method. In general, if you find yourself using the strxxx() functions on C++ std::strings, you are almost certainly doing something wrong.
Like much of the C++ Standard Library, the string class is a complex beast. To make the most of it, you really need a good reference book. I recommend The C++ Standard Library, by Nicolai Josuttis.
You can't get a char* from a string
string does not allow you free access to its internal buffer.
The closest you can get is a const char* using .c_str() if you want it null terminated or .data() if it doesn't have to be null terminated.
You can then cast the pointer returned by these functions to char* but you do this on your own risk. That being said this is a relatively safe cast to make as long as you make sure you're not changing the string. If you changed it then the pointer you got from c_str() may no longer be valid.
This code:
string str("Hello World!");
char* sp = (char*)str.c_str();
sp[5] = 'K';
is probably ok
However this:
string str("Hello World!");
char* sp = (char*)str.c_str();
str = "Chaged string";
sp[5] = 'K';
is most definitely not ok.
If you just want to assign a string literal to pw, you can do it like
char *pw = "Hello world";
If you have a C++ std::string object, the value of which you want to assign to pw, you can do it like
char *pw = some_string.c_str()
However, the value that pw points to will only be valid for the life time of some_string.
More here :
How to assign a string to char *pw in c++
GoodLUCK!!
std::string yourString("just an example");
char* charPtr = new char[yourString.size()+1];
strcpy(charPtr, yourString.c_str());
If str in your string use str.c_str() method to get the char* inside it.
Perhaps this exmaple will help you
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str ("Replace the vowels in this sentence by asterisks.");
size_t found;
found=str.find_first_of("aeiou");
while (found!=string::npos)
{
str[found]='*';
found=str.find_first_of("aeiou",found+1);
}
cout << str << endl;
return 0;
}
The C++ Standard provides two member functions of claass std::basic_string that return pointer to the first element of the string. They are c_str() and data(). But the both return const char *, So you may not use them with a function that has parameter of type char *.
As for function strchr then its first parameter is const char *. So you may use c_str() and data() with this function. However it is much better to use member function find()of class sttd::basic_string instead of strchr.