Sign in to follow this  

const char* type and string missmatch?

This topic is 4301 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

multimap<const char*, int, ltstr> multimap_order_total;

multimap_order_total.insert(pair<const char* const, int>( const_cast < char* >( ReadPosition(sort_name, Menu_Cfg).c_str() ), i));
ReadPosition(string, string) returns a string. `?? :- `?? :- `?? :-`?? :- instead of strings I get these kind of things stored. ------------------------------------------ here's another case.
string test_str="thisisatest";
multimap_order_total.insert(pair<const char* const, int>( const_cast < char* >( test_str.c_str() ), i));
this works. ------------------------------------------ now here's another example..
string test_str="thisisatest";
test_str=ReadPosition(sort_name, Menu_Cfg);
cout << test_str;

multimap_order_total.insert(pair<const char* const, int>( const_cast < char* >( test_str.c_str() ), i));
this is no good. but the cout outputs what it's supposed to output. [Edited by - Tradone on March 2, 2006 7:15:40 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
Umm, std::string::c_str() returns a temporary string, that will be invalidated when the string goes out of scope or resizes.

Why not have the multimap have std::string as the index type?


I'm not so good in using maps.
When I change to std::string I get an error that I don't know how to fix.

Share this post


Link to post
Share on other sites
Quote:
Original post by Tradone
Quote:
Original post by rip-off
Umm, std::string::c_str() returns a temporary string, that will be invalidated when the string goes out of scope or resizes.

Why not have the multimap have std::string as the index type?


I'm not so good in using maps.
When I change to std::string I get an error that I don't know how to fix.


Post it then...

Share this post


Link to post
Share on other sites

int nocase_cmp(string & s1, string& s2)
{
string::const_iterator it1=s1.begin();
string::const_iterator it2=s2.begin();

//stop when either string's end has been reached
while ( (it1!=s1.end()) && (it2!=s2.end()) )
{
if(::toupper(*it1) != ::toupper(*it2)) //letters differ?
// return -1 to indicate smaller than, 1 otherwise
return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1;
//proceed to the next character in each string
++it1;
++it2;
}
size_t size1=s1.size(), size2=s2.size();// cache lengths
//return -1,0 or 1 according to strings' lengths
if (size1==size2)
return 0;
return (size1<size2) ? -1 : 1;
}


struct ltstr
{
bool operator()(string s1, string s2) const
{
// return strcmp(s1, s2) < 0;
return nocase_cmp(s1, s2) < 0;
}
};

...
...
multimap<string, int, ltstr> multimap_order_total;
...
...
..
for( int order_i=(int)ToInt(GetCfg("total", "system/users/orders/total.cgi", SystemVar_String, SystemVar_Count)); order_i >= 1000; order_i-- ){

if(ifstream(Menu_Cfg.c_str())){
Order_TotalOrders++;
multimap_order_total.insert( ReadPosition(sort_name, Menu_Cfg) , order_i );
}
}


something like this, but I get a type mismatch on the bool i suspect it's from
ltstr....

there might be more to this ... let me find more sources..

Share this post


Link to post
Share on other sites
Try making your strings const, and making the iterators const_iterators.

If that doesnt work , post the compiler errors.

Also, use [ source ] and [ / source ] (no spaces) to make you code pretty...

EDIT : Oh yes, you could make ltstr return an int too.

Share this post


Link to post
Share on other sites
Quote:
Original post by Tradone
would that require me to change the output of ReadPosition(sort_name, Menu_Cfg) to a const string also?


No, as the map takes std::string as its key, not const std::strings.

The const thing is so that your compare functor doesnt mess with the strings that the map hands them.

Imagine the effects if your compare function ( by accident ) edited the strings in the map's index. Since we wouldn't want that, making the strings const makes everyone happy...

Share this post


Link to post
Share on other sites
Quote:
Original post by Tradone
by the way, what's the difference between char* and string?
and which is better?


char * is a char array, or c-string, of unspecified location. It could dissappear from under you if it is a local array, like this:

char str[100];

Or if it is mallocated, or newed, then if someone deletes it you will have problems.

At worst, it could be a pointer to an individual character, accidentally being used as a string.

There are many other problems, such as ensuring that the string is ended in the nul character ('\0'), so that c-string functions know its size. Also, there is no way to find out how much free sapce is at the end of the string for appending things to it.

std::string is an object that is responsible for managing an array of characters. Under the hood, it works with char arrays. But it presents an easy to understand interface to us, we really don't care what it does underneath, but from above things like copying, passing to functions, testing equality and returning them work as expected.

Share this post


Link to post
Share on other sites

multimap_order_total.insert(pair<const string, int>( const_cast < string >( ReadPosition(sort_name, Menu_Cfg).c_str() ), order_i));


shenuadmin.cpp: In function `int shenu(std::string, std::string, std::string (*)[2], int, std::string (*)[2], int, std::string)':
shenuadmin.cpp:3460: error: invalid use of const_cast with type `std::string', which is not a pointer, reference, nor a pointer-to-data-member type
shenuadmin.cpp:3460: error: invalid const_cast from type `const char*' to type `std::string'

this is all I get now.

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
Quote:
Original post by Tradone
by the way, what's the difference between char* and string?
and which is better?


char * is a char array, or c-string, of unspecified location. It could dissappear from under you if it is a local array, like this:

char str[100];

Or if it is mallocated, or newed, then if someone deletes it you will have problems.

At worst, it could be a pointer to an individual character, accidentally being used as a string.

There are many other problems, such as ensuring that the string is ended in the nul character ('\0'), so that c-string functions know its size. Also, there is no way to find out how much free sapce is at the end of the string for appending things to it.

std::string is an object that is responsible for managing an array of characters. Under the hood, it works with char arrays. But it presents an easy to understand interface to us, we really don't care what it does underneath, but from above things like copying, passing to functions, testing equality and returning them work as expected.


So the string class may be a litter slower(assuming that they are slower b/c the class has more functions and tools), but it is safer than character arrays.

Share this post


Link to post
Share on other sites
Okay , I think I got you confused.

Your insert code should look like this:


multimap_order_total.insert(pair<string, int>( ReadPosition(sort_name, Menu_Cfg, order_i));




Note the lack of const before string, and the lack of tthe const cast.

Now, the const_iterators are for your compare function, not for the printing of the multimap. The multimap code should work the way it was. If you dont mind the multimap sorting your strings case sensitive for the moment, you could try declaring the map like so:


multimap<string, int> multimap_order_total;




And comment out your ltstr and compare ignore case functions for the moment.

Quote:

CGImap query(getenv("QUERY_STRING"));
for(CGImap::iterator it = query.begin(); it != query.end(); it++) {
SystemVarPar_String[SystemVarPar_Count][0]=(*it).first;
SystemVarPar_String[SystemVarPar_Count][1]=(*it).second;
SystemVarPar_Count++;
}

shenuadmin.cpp:1568: error: using obsolete binding at `it'

looks like the first thing I need to change variable name.


I suspect that this is cause by using the variable "it" outside the for loop, not in the code you posted

Share this post


Link to post
Share on other sites

multimap<string, int> multimap_order_total;




Wait.. I think I need the third thing in the multimap, I added something yesterday so that it becomes case insensitive.


multimap<string, int, ltstr> multimap_order_total;














int nocase_cmp(const string & s1, const string& s2)
{
string::const_iterator it1=s1.begin();
string::const_iterator it2=s2.begin();

//stop when either string's end has been reached
while ( (it1!=s1.end()) && (it2!=s2.end()) )
{
if(::toupper(*it1) != ::toupper(*it2)) //letters differ?
// return -1 to indicate smaller than, 1 otherwise
return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1;
//proceed to the next character in each string
++it1;
++it2;
}
size_t size1=s1.size(), size2=s2.size();// cache lengths
//return -1,0 or 1 according to strings' lengths
if (size1==size2)
return 0;
return (size1<size2) ? -1 : 1;
}

struct ltstr
{
bool operator()(const char* s1, const char* s2) const
{
return nocase_cmp(s1, s2) < 0;
}
};




Share this post


Link to post
Share on other sites
Well. Okay.

Try this, again posting errors if it fails:


/*
replace ltstr with this
we could always give it a descriptive name ;)
*/

struct case_insensitive_test
{
int operator()(const string & s1, const string& s2) const
{
return nocase_cmp(s1,s2);
}
};

multimap<string, int, case_insensitive_test > multimap_order_total;


Share this post


Link to post
Share on other sites
I think it's fixed.
I thought my brain was going to pop.

If you still have time, I would like to ask what the reasons for that were.
Any further links would be helpful as well!

I still have to apply this script into other parts of my source code, I'll know for sure if it's working but it seems like it does.

and is this a common error among beginners?

I would like to thank you so much,
there's not much I can do for you, but to maybe bump your ratings up a little bit which I already did. Thank you once again.

Share this post


Link to post
Share on other sites
Quote:
Original post by Tradone
If you still have time, I would like to ask what the reasons for that were.


Reasons are the way the STL expects the classes (and functors) you use with it to behave.

Quote:

Any further links would be helpful as well!


This is what I use:
The STL

Its not beginner friendly, it assumes you know parts of the language you may not have yet encountered. Links more suitable for beginners can probably be found in the faqs and with a quick search for "beginner, c++ standard library" in google.

Quote:

is this a common error among beginners?


Dealing with the STL, learning how to interpret the essays it produces as error messages, etc, is all part of learning the language. I know it took me long enough. [smile]

Quote:

I still have to apply this script into other parts of my source code, I'll know for sure if it's working but it seems like it does.


good to hear.

Good Luck!

Share this post


Link to post
Share on other sites
hey that STL library is what I used.
I skimmed through it.


struct case_insensitive_test
{
bool operator()(const string & s1, const string& s2) const
{
return nocase_cmp(s1, s2) < 0;
}
};

/*
struct case_insensitive_test
{
int operator()(const string & s1, const string& s2) const
{
return nocase_cmp(s1,s2);
}
};
*/




the one on bottom didn't seem to work,
so I kind of changed it back.

everything is working fine.
Thanks!!

Share this post


Link to post
Share on other sites
yet another unrelated question..

is there like an alternative for this?

cin >> yes;
if ( yes == "yes" ){
for(int i=0; i<=1000; i++){
many many commands, including changing variables.
}
}
else{
for(int i=1000; i>=0; i--){
exactly the same commands as above, but only in descending order.
}
}



i want to only write it once!

Share this post


Link to post
Share on other sites

for (multimap<string, int, case_insensitive_test>::const_reverse_iterator const_it = multimap_order.rbegin() const; const_it != multimap_order.rend() const; ++const_it ){




and please perhaps the correct syntax for reverse iterators?

and I got those informations here:http://www.roguewave.com/support/docs/leif/sourcepro/html/stdlibref/multimap.html#sec9

Share this post


Link to post
Share on other sites

This topic is 4301 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this