converting stringc to char* ?
Hello Guru's...
I am on an adventure to learn C++, some background in different scripting languages so I am so used to having my hand held when it comes to dealing with variables.
There is a simple way to handle this I would hope, I use this a lot in my applications but need assistance in looking for the easy way to handle, maybe a function or something? Right now, I cant get this to work at all unless I specify the string in total without adding any dynamic variables.
core::stringc itemnumber = "001";
core::stringc my_string1;
core::stringc my_string2;
core::stringc my_string3;
core::stringc my_string4;
char* myexc;
my_string1 = "select * from itemtable where item='"; //stringc
my_string2 = itemnumber; //stringc
my_string3 = "' order by itemnumber";
my_string4= my_string1 + my_string2 + my_string3;
//myexc = "select * from itemtable where itemnumber='001' order by itemnumber"; // This works.
if(!db.Execute(my_string4,tbl)) // Error 2440 is here.
The error I get is:
main.cpp(100) : error C2440: '=' : cannot convert from 'irr::core::stringc' to 'char *'
I have read several pages, articles and simply cannot seem to put this together correctly. Also, just a note, this is burried within a switch statement, so, assigning the var types has to be done outside of this case statement. At anyrate, it seems to me that I need to know how to place my_string4 into either a char* or convert it to a char* that the db.execute understands.
Any help would be greatly appreciated. I would really like to understand this...
Re: converting stringc to char* ?
Oh, and when I use my_string4 in the db line like this:
I get this error.
main.cpp(103) : error C2664: 'bool Database::Execute(char *,Table &)' : cannot convert parameter 1 from 'irr::core::stringc' to 'char *'
The error above shows when I try to assign myexc = my_string4
Re: converting stringc to char* ?
found that
Code:
typedef string< c8 > stringc;
and that in the definition of irr:string
Code:
const T * c_str () const
when I assume that c8 is just a typedef for char then
Code:
f(!db.Execute(my_string4.c_str(),tbl))
should work
Kurt
EDIT:
Execute seems to want a modifyable char array. You will have to copy whats returned from my_string4.c_str() into a char array and pass that to Execute.
Re: converting stringc to char* ?
Re: converting stringc to char* ?
ok, I changed this to open something else to just make sure it didnt have anything to do with the data I was trying to pull. Here is what I have now:
my_string1 = "select * from usertable where loginid='";
//my_string2 = logidin;
my_string2 = "digoxy";
my_string3 = "' order by loginid";
my_string4= my_string1 + my_string2 + my_string3;
printf("\nUserID %s",my_string4);
myexc = my_string4; // Error is here.
//myexc = "select * from usertable where loginid='digoxy' order by loginid";
if(!db.Execute(myexc,tbl))
These two methods work just fine-
1 - if(!db.Execute("select * from usertable where loginid='digoxy' order by loginid",tbl))
2 - myexc = "select * from usertable where loginid='digoxy' order by loginid";if(!db.Execute(myexc,tbl))
I need to use the combined my_string4 tho!
ERROR with :
main.cpp(100) : error C2440: '=' : cannot convert from 'irr::core::stringc' to 'char *'
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
@Zuk If there is some type that I should use here other that stringc what would that be you think? I know that the data I am getting from the network are c8 so I should be able to parse this data, if I were to change these vars from irr::core::stringc what would you recommend? I think they are a standard c8 now but for some reason. BTW I did try your solution before the change but came up with the same error, only in the DB line. In all, I think it has to do with the set myexc with my_string4, what is the right process? You mention a copy, how is this done correctly?
@hoxsiew core is within my network library, it assures me the data sent is of c8.
Re: converting stringc to char* ?
Well, I'm assuming that by "c8" you mean an 8-bit integer, more commonly called a char. That isn't a common name for such a type; usually you'd see char or unsigned char or uint8_t. On Windows you might see it called BYTE.
Why not just use a std::string, or, if you need the ability to write directly into a buffer, a std::vector<char>? I suppose if you really want to, you could make it a std::vector<c8> instead.
Re: converting stringc to char* ?
Thanks for the reply lindley, if you were to put this together, can you show me how you would write it? I want to see this work any possible way it might work.
std::string = "this is line1 "
std::string2 = "this is line2 "
std::string3 = std::string + std::string2
char * myexc;
myexc = string3
Re: converting stringc to char* ?
Code:
std::string str1 = "this is line1 "
std::string str2 = "this is line2 "
std::string str3 = str1 + str2;
const char * myexc = str3.c_str();
// Note that myexc will be invalidated if str3 changes in any way
Or, if you really need the char* to be modifiable,
Code:
std::string str1 = "this is line1 "
std::string str2 = "this is line2 "
std::vector<char> str3(str1.begin(),str1.end());
str3.insert(str3.end(), str2.begin(), str2.end());
// Note: I'm not certain whether this would properly NULL-terminate the string. If not, then you can do:
// str3.push_back(0);
char *myexc = &str3[0];
Re: converting stringc to char* ?
As Trivial as it is, here is the solution that seems to work.
str[40]
strcpy_s (str,"select * from usertable where loginid='");
strcat_s (str, logidin.c_str());
strcat_s (str, "' and loginpw ='");
strcat_s(str, logidin.c_str());
strcat_s(str, "' order by loginid");
//std::cout << str << endl;
if(!db.Execute(str,tbl))
Re: converting stringc to char* ?
Definitely wrong. You've provided a 40-character buffer, yet you're trying to cram more than that into it. (Your very first string is about 40 characters). That's a classic C-style string mistake, and indeed the primary reason why std::string was developed in the first place.
Re: converting stringc to char* ?
Yes Lindley, it was a bit small, I have increased it now though. I jumped the gun a bit in posting that is all. I do appreciate the feedback. I have been working to pass all kinds of data back and forth from the DB and its all working fine now. I also had to parse some data using the token gen, this works great.
Do you have any suggestions very specific on how to clean up that mess now? When assigning the string, do I need to set it to null or something?
Re: converting stringc to char* ?
Quote:
Originally Posted by
digoxy
As Trivial as it is, here is the solution that seems to work.
str[40]
strcpy_s (str,"select * from usertable where loginid='");
strcat_s (str, logidin.c_str());
strcat_s (str, "' and loginpw ='");
strcat_s(str, logidin.c_str());
strcat_s(str, "' order by loginid");
//std::cout << str << endl;
if(!db.Execute(str,tbl))
The very same code written in C++:
Code:
#include <string>
//...
std::string str = "select * from usertable where loginid='"';
str += logidin + "' and loginpw ='" + logidin + "' order by loginid";
if(!db.Execute(str.c_str(),tbl))
It now doesn't matter if the string is 40 bytes or 40,000 bytes -- the same code still works.
Regards,
Paul McKenzie
Re: converting stringc to char* ?
Except the the OP's db.Execute() takes a char *, not const char *; the main reason this thread has gone on for as long as it has.
Re: converting stringc to char* ?
Hello Paul, I did drop this in just to see what it would do, I have since tokenized the login id and pw. Here is the way the string looks.
Code:
std::string str2 = "select * from usertable where loginid='"'; <-is this not an extra ' right before ; ?
str2 += tokens[0].c_str() + "' and loginpw ='" + tokens[1].c_str() + "' order by loginid";
if(!db.Execute(str2.c_str(),tbl))
Will play with it some more and see what it can do. It appears right now that hoxsiew may be right tho. I can see that I have some errors about pointers and something about newline. This is a nice little packaged deal with the create line in 1 swing! I think the errors may be coming from the quotes though. This code being buried in a case statement griped at me a bit to, I had to init str2, I did this as a char[200]. If you see anything here that might be of use to change it up a bit, I dont mind playing with it. I have it in the script just commented now so I can ding around with it! :)
Code:
1>.\main.cpp(130) : error C2001: newline in constant
1>.\main.cpp(130) : error C2143: syntax error : missing ';' before 'constant'
1>.\main.cpp(131) : error C2146: syntax error : missing ';' before identifier 'str2'
1>.\main.cpp(131) : error C2110: '+' : cannot add two pointers
1>.\main.cpp(132) : error C2228: left of '.c_str' must have class/struct/union
REALLY appreciate your help guys,
digz...
Re: converting stringc to char* ?
Oh, and Lindley, I think what I wound up doing here is using your method with tokens, it seems dropping this into a vec was something I needed to do anyway as I am sending a stream from one server to the other and having to parse the searches etc. so, now what I get and parse is something like this
login|pw|string|bool|bool|string .. ..
creating the tokens allows me to use the data however I need to through the DB or whatever else I may need to do with it in this setup.
Figured I would share what I have so far, it might help someone else, but, I think in all, there may be a smooth way to do this over all. always learning with C++ and finding 100 ways to do one thing and looking for that best practice is always something for me. at anyrate, here we go..
Code:
// Puts the packet information into logidin var.
packet >> logidin;
strcpy_s (str, logidin.c_str());
// vec the string. (str is our string, tokens is the assigned vec name
Tokenize(str, tokens);
//copy(tokens.begin(), tokens.end(), ostream_iterator<string>(cout, ", "));
//print some stuff to the console, NOTE: jim, this should be a db.updatelog(time, date, connection info, IP) etc.
// send out some console info
std::cout << "Client login " << packet.Id() << " says: " << "X" << logidin.c_str() << "X";
std::cout << std::endl;
//build query string for SQL DB using tokenized string vars.
strcpy_s (str,"select * from usertable where loginid='");
strcat_s (str, tokens[0].c_str());
strcat_s (str, "' and loginpw ='");
strcat_s (str, tokens[1].c_str());
strcat_s(str, "' order by loginid");
// print some stuff to console.
//std::cout << "SQL String = " << str << endl;
//execute the db get.
if(!db.Execute(str,tbl))
and the tokenizer, this I found through goooogle.
Code:
// call it tokenize(str, tokens)
void Tokenize(const string& str,
vector<string>& tokens,
const string& delimiters = "|")
{
// Skip delimiters at beginning.
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
// Find first "non-delimiter".
string::size_type pos = str.find_first_of(delimiters, lastPos);
while (string::npos != pos || string::npos != lastPos)
{
// Found a token, add it to the vector.
tokens.push_back(str.substr(lastPos, pos - lastPos));
// Skip delimiters. Note the "not_of"
lastPos = str.find_first_not_of(delimiters, pos);
// Find next "non-delimiter"
pos = str.find_first_of(delimiters, lastPos);
}
}
Re: converting stringc to char* ?
Personally, I'd use sprintf() or, if using VC, CString::Format() to build the sql request, but I prefer C-style coding over std containers for the most part (that's the way I learned):
Code:
int itemnumber=101;
char sqlbuf[100]; //make it big enough to hold your entire statement
sprintf(buf,"SELECT * FROM USERTABLE WHERE itemnumber='%d' AND loginpw='%s' ORDER BY loginid",itemnumber,"MyPassword");
if(!db.Execute(sqlbuf,tbl)){
//...
}
Re: converting stringc to char* ?
You should use one or the other approach. Mixing them up just tends to cause confusion. Right now, you're using a combination of strcpy() and std::string fairly intermingled, which I'd consider bad form. Also, don't over-use the c_str() method; it isn't needed for cout or for std::string concatenation, or for pretty much anything else except functions requiring a const char* explicitly.
Re: converting stringc to char* ?
Quote:
Originally Posted by
digoxy
Hello Paul, I did drop this in just to see what it would do, I have since tokenized the login id and pw. Here is the way the I did this as a char[200].
Do you have a check if you have exceeded 200 characters? If you don't then this is deemed a vulnerability in your program, as buffer overflow can occur.
That's why std::string is safer.
Quote:
If you see anything here that might be of use to change it up a bit, I dont mind playing with it. I have it in the script just commented now so I can ding around with it! :)
Just fix the compiler errors. If all the problem is just quotes, it takes a few seconds to fix them.
As to char*, the following should be safer:
Code:
#include <string>
#include <vector>
//...
std::string str = "select * from usertable where loginid='";
str += logidin + "' and loginpw ='" + logidin + "' order by loginid";
std::vector<char> tempV(str.begin(), str.end());
tempV.push_back(0);
if(!db.Execute(&tempV[0], tbl))
{ }
Regards,
Paul McKenzie
Re: converting stringc to char* ?
^I'm not sure that doing that would properly null-terminate the string. You may need to push_back a 0 at the end. Actually, it would be good to know either way for certain.
Re: converting stringc to char* ?
Quote:
Originally Posted by
Lindley
^I'm not sure that doing that would properly null-terminate the string. You may need to push_back a 0 at the end. Actually, it would be good to know either way for certain.
Yes, it wouldn't hurt to push_back a 0 onto that.
Regards,
Paul McKenzie