Difference between sending text as string and text between quotation marks - c++

I use mysql++ library to connect to my database. I've created a Connection and Query:
Connection conn(false);
conn.connect("database", "localhost", "user", "pass");
Query query = conn.query();
Then I can send a query to the database like:
query << "select name from my_table1, my_table2 where age=20"
But I'd like to send a number variable instead of 20. I tried to do that in that way:
std::stringstream ss; //create a stringstream
ss << my_number //add number to the stream
std::string number = ss.str();
query << "select name from my_table1, my_table2 where age="+number;
Unfortunately, it doesn't work.
My second problem is analogous. I create an QPixmap object (here QPixmap doesn't matter anyway) and i've to give the constructor a path to my image:
std:string name;
(...)
std::string path = "/home/root/img/"+name+".png"; //name is a variable string
QPixmap *tmp = new QPixmap(QString::fromUtf8(path.c_str())); //conversion from string to QString

query << "select name from my_table1, my_table2 where age="+number;
should be:
query << "select name from my_table1, my_table2 where age=" << number;
since + is not a valid C++ streams concatenation operator.
What's the problem with the QPixmap? Maybe that should be a separate question?

For your second issue I'd recommend changing it from this:
std:string name;
(...)
std::string path = "/home/root/img/"+name+".png"; //name is a variable string
To this:
const QString name;
...
const QString path = QString("/home/root/img/%1.png").arg(name);
....
QPixmap tmp(path);

Related

Parse string data according to template in qt c++

I have a string which consist of data along with spaces i want to sort this string into particular variables
eg.
" Company Name : ABC Department : TESTING";
i want to split this string and get the company name and department name to add to their particular variable
You will have a pain in the neck for achieving that taks because the data is ill formatted,
your goal is to obtain from the string something like:
Company Name = ABC
Department = TESTING
even using the method split, you need a token that you dont have...
the suggestion i can provide is to redefine those strings in something well formatted and parsable... json is a good candidate for this task
imagine this example using json objects:
QString str3 = "{\"Company Name\" : \"ABC\", \"Department\" : \"TESTING\", \"Number\" : 123, \"Updated\" : false}";
then you need to "parse" the string into a json object, then get those "values" for the "keys"
like:
QJsonDocument doc1 = QJsonDocument::fromJson(str3.toUtf8());
QJsonValue company = doc1["Company Name"];
QJsonValue dept = doc1["Department"];
QJsonValue number = doc1["Number"];
QJsonValue updated = doc1["Updated"];
qDebug()<< "Company: " << company.toString();
qDebug()<< "Department: " << dept.toString();
qDebug()<< "Number: " << number.toInt();
qDebug()<< "Updated: " << updated.toBool();
your output will look like:
Company: "ABC"
Department: "TESTING"
Number: 123
Updated: false

Use writer/reader for multiple fields

The following is my constructor for a Student object. I will be using a list of student. I need to store the list so even if the program is turned off, I can still access all the contents. The only way I could think of was to use reader/writer and a text file.
1) Is there a more efficient way to store this information?
2) If not, how can I use reader/writer to store each field?
public Student(String firstName, String lastName, String gender, String
state, String school, String lit, String wakeUp, String sleep, String
social,String contactInfo, String country, String major) {
this.firstName = firstName;
this.lastName = lastName;
this.gender = gender;
this.state = state;
this.school = school;
this.lit = lit;
this.wakeUp = wakeUp;
this.sleep = sleep;
this.social = social;
this.contactInfo = contactInfo;
this.country = country;
this.major = major;
}
The possibilities are really project specific and subjective.
Some possibilities include:
CSV file which makes it easy for exporting to other programs and parsing data
Online server which allows access from any computer that has the
program and an internet connection
Text file which works for local devices that won't require many
additions
It really just depends on how you want to implement it and what method suits your needs best.
To use reader/writer to store your fields, you could use the accessor methods of each variable to store them line by line in your text file. Below is some sample code to get you started on writing to the file:
PrintWriter outputStream = null;
try {
outputStream = new PrintWriter(new FileOutputStream(FILE_LOCATION));
}
catch (FileNotFoundException ex) {
JOptionPane optionPane = new JOptionPane("Unable to write to file\n " + FILE_LOCATION, JOptionPane.ERROR_MESSAGE);
JDialog dialog = optionPane.createDialog("Error!");
dialog.setAlwaysOnTop(true);
dialog.setVisible(true);
System.exit(0);
}
Iterator<YOUR_OBJECT> i = this.List.iterator();
YOUR_OBJECT temp = null;
while (i.hasNext()) {
temp = i.next();
if (temp instanceof YOUR_OBJECT) {
outputStream.println(temp.getAttribute());
}
}
outputStream.close();

json serialize c++

I have this C++ code, and am having trouble json serializing it.
string uInput;
string const& retInput;
while(!std::cin.eof()) {
getline(cin, uInput);
JSONExample source; //JSON enabled class from jsonserialize.h
source.text = uInput;
//create JSON from producer
std::string json = JSON::producer<JSONExample>::convert(source); //string -> returns {"JSONExample":{"text":"hi"}}
//then create new instance from a consumer...
JSONExample sink = JSON::consumer<JSONExample>::convert(json);
//retInput = serialize(sink);
// Json::FastWriter fastWriter;
// retInput = fastWriter.write(uInput);
retInput = static_cast<string const&>(uInput);
pubnub::futres fr_2 = pb_2.publish(chan, retInput);
cout << "user input as json which should be published is " << retInput<< std::endl;
while(!cin.eof()) {
getline(cin, uInput);
newInput = "\"\\\"";
newInput += uInput;
newInput += "\\\"\"";
Instead of typing in the message like "\"hi\"", this code takes "hi" and does it.
If the change you described made the "Invalid JSON" disappear, then a "more correct" solution would be, AFAICT, to change the publish() line to:
pubnub::futres fr_2 = pb_2.publish(chan, json);
Because json already has JSON serialized data. Of course, if that JSON is what you want to publish.

PQexecParams in C++, query error

I'm using pqlib with postgresql version 9.1.11
I have the following code
const char *spid = std::to_string(pid).c_str();
PGresult *res;
const char *paramValues[2] = {u->getID().c_str(), spid};
std::string table;
table = table.append("public.\"").append(Constants::USER_PATTERNS_TABLE).append("\"");
std::string param_name_pid = Constants::RELATION_TABLE_PATTERN_ID;
std::string param_name_uid = Constants::RELATION_TABLE_USER_ID;
std::string command = Constants::INSERT_COMMAND + table + " (" + param_name_uid + ", " + param_name_pid + ") VALUES ($1, $2::int)";
std::cout << "command: " << command << std::endl;
res = PQexecParams(conn, command.c_str(), 2, NULL, paramValues, NULL, NULL,0);
Where
INSERT_COMMAND = "INSERT INTO " (string)
USER_PATTERN_TABLE = "User_Patterns" (string)
RELATION_TABLE_PATTERN_ID = "pattern_id" (string)
RELATION_TABLE_USER_ID = "user_id" (string)
pid = an int
u->getID() = a string
conn = the connection to the db
The table "User_Patterns" is defined as
CREATE TABLE "User_Patterns"(
user_id TEXT references public."User" (id) ON UPDATE CASCADE ON DELETE CASCADE
,pattern_id BIGSERIAL references public."Pattern" (id) ON UPDATE CASCADE
,CONSTRAINT user_patterns_pkey PRIMARY KEY (user_id,pattern_id) -- explicit pk
)WITH (
OIDS=FALSE
);
I already have a user and a pattern loaded into their respective tables.
The command generated is :
INSERT INTO public."User_Patterns" (user_id, pattern_id) VALUES ($1, $2::int)
I also tried with $2, $2::bigint, $2::int4
The problem is:
I receive the error :
ERROR: invalid input syntax for integer: "public.""
I already use PQexecParams to store users and patterns, the only difference is that they all have text/xml fields (the only int field on patterns is a serial one and I don't store that value myself) but because the user_patterns is a relation table I need to store and int for the pattern_id.
I already read the docs for pqlib and saw the examples, both are useless.
The problem is in the lines:
const char *spid = std::to_string(pid).c_str();
const char *paramValues[2] = {u->getID().c_str(), spid};
std::to_string(pid) creates temporary string and .c_str() returns a pointer to an internal representation of this string, which is destroyed at the end of the line, resulting in a dead pointer. You may also see answer to the question
stringstream::str copy lifetime

Reading SQL table in C++

I am trying to read a SQL Server table in C++ using a function like this..
CCommand<CDynamicAccessor>* Read(char* tblName)
{
wostringstream query;
query << "SELECT * FROM " << tblName;
return dataSource -> Query (query);
}
which calls this other function
CCommand<CDynamicAccessor>* Query(wostringstream& query)
{
HRESULT hr;
hr = _cmd.Open(_sess, _T(query.str().c_str()));
if (FAILED(hr))
{
std::wcout<<query.str().c_str() << "\n";
THROW_EXCEPTION("Command not executed.");
}
return &_cmd;
}
The problem is when I try to retrieve the column values using something like this
char* column20= (char*)cmd->GetValue("column20");
char* column21= (char*)cmd->GetValue("column21"); //Error
Because in the column20 I get the full string ex. "Value1"
But in the column21 I only get the first character ex. "V", when I should get "Value2"
Is there any limitation in size or something like that which do not allow me to retrieve the full string for column21?
If so, what is the best way to solve this issue?
Most probably the result is a wchar_t * string and you cast it to char *