🔒 Locked
String manipulation
Advertisement
Original Post
Ok, i have 10 char* pointers i need to add to a map<> template (it is the key type). I go through a loop. // 10 Items for (char i=0, char*ch; i < 10 ; i++) { sprintf(ch, "Item%d", i); MapList.Add(SomeItem, ch); } but then when i check the map for that same item, it returns an error saying it's not there... MapList.GetItem("Item0") <-- returns NULL what's wrong?
it is really just that, i have a
Quote:
Original post by EvilKnuckles666
Ok, i have 10 char* pointers i need to add to a map<> template (it is the key type). I go through a loop.
// 10 Items
for (char i=0, char*ch; i < 10 ; i++)
{
sprintf(ch, "Item%d", i);
MapList.Add(SomeItem, ch);
}
but then when i check the map for that same item, it returns an error saying it's not there...
MapList.GetItem("Item0") <-- returns NULL
what's wrong?
I see one problem here:
sprintf(ch, "Item%d", i);In your for loop. 'ch' is being declared. The problem is you're not allocating memory for 'ch' (malloc, realloc etc..) You're writing into an uninitialized-unknown memory space. Which is bad.
[edit: I see you're using C++. substitute malloc/relloac with the C++ equivalents]
yes i am. it's in the beginning line in the for loop.
for (char i=0, char* ch; i<10 ; i++)
for (char i=0, char* ch; i<10 ; i++)
++ for eddie.
Also, though it might depend on your setup, the map was not declared to do string comparesson on the key. It's just comparing pointers, which even if you malloc the key properly, the string literal you're checking against won't have the same pointer. Thus the map will not consider it equal, even though the text is the same.
Here at the top is example code to setup the map [the 3rd template parameter to it to be specific] to do what you want. Though eddie is correct, and proper memory management with char*'s will also be a problem.
And further:
is non-sense.
i is a char, not a ?double? which is what %d is looking for, meaning 0 is not what will be at the end of that string, meaning it won't match anyways.
std::string, and stringstream are your friends. Even if you use char*'s correctly, it's a pain to remember niggling details like memory management and what %code is a certain type in *printf functions. Especially when busy trying to learn other stuff.
[edit: correcting...]
Also, though it might depend on your setup, the map was not declared to do string comparesson on the key. It's just comparing pointers, which even if you malloc the key properly, the string literal you're checking against won't have the same pointer. Thus the map will not consider it equal, even though the text is the same.
Here at the top is example code to setup the map [the 3rd template parameter to it to be specific] to do what you want. Though eddie is correct, and proper memory management with char*'s will also be a problem.
And further:
sprintf(ch,"Item%d",i);is non-sense.
i is a char, not a ?double? which is what %d is looking for, meaning 0 is not what will be at the end of that string, meaning it won't match anyways.
std::string, and stringstream are your friends. Even if you use char*'s correctly, it's a pain to remember niggling details like memory management and what %code is a certain type in *printf functions. Especially when busy trying to learn other stuff.
[edit: correcting...]
Quote:
Original post by EvilKnuckles666
yes i am. it's in the beginning line in the for loop.
for (char i=0, char* ch; i<10 ; i++)
char *ch will create a character pointer, but it won't be pointing to anything unless you new or malloc it. Right now, it's pointing to something random. Probably something you don't want to overwrite.
To do what you think you're doing now, do either of these:
char *ch = new char[256]; // or however long you want it
char ch[256]; // or however long you want it
After doing that, you can use sprintf on the strings.
Quote:
Original post by EvilKnuckles666
yes i am. it's in the beginning line in the for loop.
for (char i=0, char* ch; i<10 ; i++)
No you did not.
You forgot, or don't know, that, pointers need to be intialized with memory first in order to store something in the pointer variable.
Example:
In C:
ch = malloc(10 * sizeof(char));In C++ .. something like this:
ch = new[10];
Here's some code that should work. [edit: for the map problems.]
Note that the struct "bar" does not need to do manual deletion of the copied keys, and that "foo" will.
output
[edit2: And here's the code for the sprintf issues. Note, the char* in "bar" was changed to const char * to make this work nicer.]
Note that the struct "bar" does not need to do manual deletion of the copied keys, and that "foo" will.
#include <map>#include <stdio.h>#include <stdlib.h>#include <iostream>#include <string>#include <sstream>#include <utility>#define bzero(p, l) memset(p, 0, l)using namespace std;struct ltstr{ bool operator()(const char* s1, const char* s2) const { return strcmp(s1, s2) < 0; }};struct foo{ map<char *, int, ltstr> foomap; void add(char *k, int v){ // // // char *kcopy=0; kcopy=(char *)malloc(strlen(k)+1); strcpy(kcopy,k); foomap.insert(make_pair(kcopy,v)); } int fetch(char *k){ // // // map<char *,int, ltstr>::iterator it; it=foomap.find(k); if(it!=foomap.end()){ return(it->second); }else{ return(0); } }};struct bar{ map<string, int> barmap; void add(char *k, int v){ // // // barmap.insert(make_pair(k,v)); } int fetch(char *k){ // // // map<string,int>::iterator it; it=barmap.find(k); if(it!=barmap.end()){ return(it->second); }else{ return(0); } }};int main(){//////foo f;bar b;f.add("cow",1);f.add("duck",2);cout << "cow: " << f.fetch("cow") << "\n";cout << "duck: " << f.fetch("duck") << "\n";b.add("moose",42);b.add("goat",-5);cout << "moose: " << b.fetch("moose") << "\n";cout << "goat: " << b.fetch("goat") << "\n";}output
> ./testcow: 1duck: 2moose: 42goat: -5[edit2: And here's the code for the sprintf issues. Note, the char* in "bar" was changed to const char * to make this work nicer.]
int x;char *buf;buf=(char *)malloc(50);bzero(buf,50);for(x=3; x<8; x++){ sprintf(buf,"Item%i",x); f.add(buf,x*x);}free(buf);cout << "Item 5 (5*5): " << f.fetch("Item5") << "\n";string ss;for(x=3;x<8;x++){ ss="Item"+x; b.add(ss.c_str(),x*9);}cout << "Item 6 (6*9): " << b.fetch("Item6") << "\n";
soo all would i have to do is add that struct at the top of my code and put:
map
as my map declaration?
edit: Or would i have to change things around? (hopefully not...)
map
as my map declaration?
edit: Or would i have to change things around? (hopefully not...)
hmmm, now i'm thinking of just going with:
map
think that would be better/easier?
map
think that would be better/easier?
Quote:
Original post by EvilKnuckles666
hmmm, now i'm thinking of just going with:
map
When you are using the standard C++ library, you might as well try to use all the provided components if they fit your needs. If you are in need of using a string data type for the key, choose std::string over char*. It just makes life better for you.
geez... now it can't see they're the same again...
for (char i=0 ; i < 10 ; i++)
{
string str;
str = "Level_1_Enemy_" + i;
MapList.Add(Item, str);
}
GetItem("Level_1_Enemy_0")
yet again returns NULL...
edit: and now my map is map
for (char i=0 ; i < 10 ; i++)
{
string str;
str = "Level_1_Enemy_" + i;
MapList.Add(Item, str);
}
GetItem("Level_1_Enemy_0")
yet again returns NULL...
edit: and now my map is map
When you want to do what you just did, you will need to use the stringstream to build a string.
If that does not work right, check over your Add function. Perhaps there is a logic error there that makes the problem happen.
Oh and as to why I used ints over char's here's what your code is doing:
You should have had:
for ( char i = '0'; i <= '9'; i++ )
#include <sstream>...for ( int i = 0; i < 10; i++ ){ stringstream ss; ss << "Level_1_Enemy_" << i; MapList.Add( Item, ss.str() );}If that does not work right, check over your Add function. Perhaps there is a logic error there that makes the problem happen.
Oh and as to why I used ints over char's here's what your code is doing:
Level_1_Enemy_Level_1_Enemy_☺Level_1_Enemy_☻Level_1_Enemy_♥Level_1_Enemy_♦Level_1_Enemy_♣Level_1_Enemy_♠Level_1_Enemy_Level_1_Enemy_Level_1_Enemy_You should have had:
for ( char i = '0'; i <= '9'; i++ )
i did what you said and this came up:
ss.str() = "Level_1_Enemy_0ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««îþîþ"
what's all that stuff after it..
ss.str() = "Level_1_Enemy_0ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««îþîþ"
what's all that stuff after it..
Quote:
Original post by EvilKnuckles666
i did what you said and this came up:
ss.str() = "Level_1_Enemy_0ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««îþîþ"
what's all that stuff after it..
Are you debugging? If you are, don't worry about it, it's just there, I see it too. I just made this program
#include <sstream>#include <string>#include <iostream>#include <map>using namespace std;void main(){ for ( int i = 0; i < 10; i++ ) { stringstream ss; ss << "Level_1_Enemy_" << i; cout << ss.str() << endl; }}With this output
Level_1_Enemy_0Level_1_Enemy_1Level_1_Enemy_2Level_1_Enemy_3Level_1_Enemy_4Level_1_Enemy_5Level_1_Enemy_6Level_1_Enemy_7Level_1_Enemy_8Level_1_Enemy_9Press any key to continueSo nothings wrong with the values.
yea, it's what came up in the locals in debug mode
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement