I have a set of strings and I need to access each one and compare the first letter of the string to a char and stop if they are the same. How do I go through that? I tried with
char* p;
for (std::set<string>::iterator iter=myset.begin(); iter!=myset.end();iter++)
{p = *iter;
if (p==characterForComparison) return 0;
}
but that does not pass the compiler, it says
error C2440: '=' : cannot convert from 'std::basic_string<_Elem,_Traits,_Ax>' to 'char *'
How do I solve this? What I need is fairly simple, so I need as simple a solution as I can get, just go through all the strings, compare the first letter, and if they are the same, return 0;
To compare first character of std::string just do:
if (!(*iter).empty() &&
(*iter)[0] == characterForComparison)
{
}
To access first element in a string, string provides operator[], front(), or use begin to get reference to first element. see std::string page.
Since your set contains std::strings, dereferencing the iterator gives you a string, not its first character. Use operator [] instead:
p = (*iter)[0];
*iter is a string, try
char p;
//...
p = (*iter)[0]
You have two problems. The first is that you try to assign a std::string object to a char*. The second is if you want the first character, then p should be declared as a character and not a pointer to a character.
And of course, there's really no need to store the character in a temporary variable like p, at least not in such a simple case such as yours. Use it directly from the string like
if ((*iter)[0] == characterForComparison) { /* do something */ }
if you can use C++11:
for(auto s : myset)
{
if(s[0] == characterForComparison)
{
return 0;
}
}
A C++ string is not convertible to a C-style string. *iter gives you a C++ string.
If you want to actually compare the first character of a string, then.
if ((*iter)[0] == 'a')
would do the trick.
If you actually need a const char *, you can use:
p = iter->c_str();
Note however that this is a CONSTANT string, you shouldn't modify it.
You can also use the STL algorithms.
If you can use C++11:
bool set_condition(const char c, const set<string>& s)
{
auto position =
find_if(s.cbegin(), s.cend(), [c](const string& s) { return s[0] == c; } );
return (position != s.cend() );
}
try to wrap the char in an instance of std:string:
std:string comp(characterForComparison);
and
retrieve the first character with [0]
Related
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");
}
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.
For a program I'm writing based on specifications, a variable is passed in to a function as a string. I need to set that string to a char variable in order to set another variable. How would I go about doing this?
This is it in the header file:
void setDisplayChar(char displayCharToSet);
this is the function that sets it:
void Entity::setElementData(string elementName, string value){
if(elementName == "name"){
setName(value);
}
else if(elementName == "displayChar"){
// char c;
// c = value.c_str();
setDisplayChar('x');//cant get it to convert :(
}
else if(elementName == "property"){
this->properties.push_back(value);
}
}
Thanks for the help in advanced!
You can get a specific character from a string simply by indexing it. For example, the fifth character of str is str[4] (off by one since the first character is str[0]).
Keep in mind you'll run into problems if the string is shorter than your index thinks it is.
c_str(), as you have in your comments, gives you a char* representation (the whole string as a C "string", more correctly a pointer to the first character) rather than a char.
You could equally index that but there's no point in this particular case.
you just need to use value[0] and that returns the first char.
char c = value[0];
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);
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.