-8

I create a small app in Qt Creator. I wanted this code in my QDialog constructor, but it doesn't work.

std::string wyniki = "apg -q -n " + n + " -m " + m + " -x " + sx + " -a " + a;
if(exclude != "") wyniki+=" -E " + exclude.toUtf8().constData();
if(a==1)wyniki += " -M " + mode;
std::string result = exec(wyniki.c_str());
ui->plainTextEdit->setPlainText(qstr(result));

Compiler messages:

../APG-GUI/scores.cpp: In constructor 'Scores::Scores(QWidget*, int, int, int, int, QString, QString)':
../APG-GUI/scores.cpp:36:45: error: invalid operands of types 'const char*' and 'const char [5]' to binary 'operator+'
     std::string wyniki = "apg -q -n " + n + " -m " + m + " -x " + sx + " -a " + a;
                                             ^
../APG-GUI/scores.cpp:37:67: error: invalid operands of types 'const char [5]' and 'const char*' to binary 'operator+'
     if(exclude != "") wyniki+=" -E " + exclude.toUtf8().constData();
                                                                   ^
../APG-GUI/scores.cpp:38:20: error: no match for 'operator+=' (operand types are 'std::string {aka std::basic_string<char>}' and 'const QString')
     if(a==1)wyniki += " -M " + mode;
                    ^
../APG-GUI/scores.cpp:38:20: note: candidates are:
In file included from /usr/include/c++/4.9/string:52:0,
                 from /opt/Qt/5.3/gcc_64/include/QtCore/qstring.h:50,
                 from /opt/Qt/5.3/gcc_64/include/QtCore/qobject.h:49,
                 from /opt/Qt/5.3/gcc_64/include/QtWidgets/qwidget.h:46,
                 from /opt/Qt/5.3/gcc_64/include/QtWidgets/qdialog.h:45,
                 from /opt/Qt/5.3/gcc_64/include/QtWidgets/QDialog:1,
                 from ../APG-GUI/scores.h:4,
                 from ../APG-GUI/scores.cpp:1:
/usr/include/c++/4.9/bits/basic_string.h:949:7: note: std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator+=(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
       operator+=(const basic_string& __str)
       ^
/usr/include/c++/4.9/bits/basic_string.h:949:7: note:   no known conversion for argument 1 from 'const QString' to 'const std::basic_string<char>&'
/usr/include/c++/4.9/bits/basic_string.h:958:7: note: std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator+=(const _CharT*) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
       operator+=(const _CharT* __s)
       ^
/usr/include/c++/4.9/bits/basic_string.h:958:7: note:   no known conversion for argument 1 from 'const QString' to 'const char*'
/usr/include/c++/4.9/bits/basic_string.h:967:7: note: std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator+=(_CharT) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
       operator+=(_CharT __c)
       ^
/usr/include/c++/4.9/bits/basic_string.h:967:7: note:   no known conversion for argument 1 from 'const QString' to 'char'
../APG-GUI/scores.cpp:39:45: error: no matching function for call to 'Scores::exec(const char*)'
     std::string result = exec(wyniki.c_str());
                                             ^
../APG-GUI/scores.cpp:39:45: note: candidate is:
In file included from /opt/Qt/5.3/gcc_64/include/QtWidgets/QDialog:1:0,
                 from ../APG-GUI/scores.h:4,
                 from ../APG-GUI/scores.cpp:1:
/opt/Qt/5.3/gcc_64/include/QtWidgets/qdialog.h:93:17: note: virtual int QDialog::exec()
     virtual int exec();
                 ^
/opt/Qt/5.3/gcc_64/include/QtWidgets/qdialog.h:93:17: note:   candidate expects 0 arguments, 1 provided
../APG-GUI/scores.cpp:40:48: error: 'qstr' was not declared in this scope
     ui->plainTextEdit->setPlainText(qstr(result));

I exactly do not know reasons of that malfunction. Why I can't use =+ operator? That's built-into the C++! Everything I have (I think I have) propely declared and checked that to times. I am beginner to Qt, so maybe I did something wrong. I was looking for solution in Internet, but, unfortunately, didn't find anything according to my problem. Below I post header's I use and variables declarations:

#include "scores.h"
#include "cstdio"
#include "ui_scores.h"
#include "cstdlib"
#include "iostream"
#include "string"
int n,m,sx,a;
QString mode, exclude;

My constructor code (which includes "bad" lines):

Scores::Scores(QWidget *parent, int nk, int mk, int xk, int ak, QString modesk, QString excludek) :
    QDialog(parent),
    ui(new Ui::Scores)
{
    n = nk;
    m = mk;
    a = ak;
    mode = modesk;
    sx = xk;
    exclude = excludek;
    ui->setupUi(this);
    std::string wyniki = std::string("apg -q -n ") + n + " -m " + m + " -x " + sx + " -a " + a; //badline
    if(exclude != "") wyniki+=" -E " + exclude.toUtf8().constData(); //badline
    if(a==1)wyniki += " -M " + mode; //badline 
    std::string result = exec(wyniki.c_str()); //badline
    ui->plainTextEdit->setPlainText(qstr(result));
}
vsoftco
  • 55,410
  • 12
  • 139
  • 252
TN888
  • 7,659
  • 9
  • 48
  • 84
  • It is not built into C++, but the standard library, but you need to provide an [SSCCE](http://sscce.org). What is `n`, `m`, etc? – László Papp Jul 04 '14 at 11:26
  • 1
    Read the error messages carefully. They are telling you exactly what is going on. – juanchopanza Jul 04 '14 at 11:27
  • @FinalContest I gave you the list of my variables – TN888 Jul 04 '14 at 11:29
  • @Ty221: I mean give a self-explanatory code that can be compiled not chunks in reverse order and all that. – László Papp Jul 04 '14 at 11:30
  • 2
    You mix QString with std::string and even QByteArray, no wonder you get this errors. Why not stick to one and convert everything in one step at the end into the correct format. – Flovdis Jul 04 '14 at 11:31
  • @Flovdis: he may get the strings from different sources from different types. That is not the main issue here. The error is obvious as juanchopanza claimed, but I am surprised that OP does not supply a self-sufficient code that reproduces the issue. IMHO, such ops do not deserve help. – László Papp Jul 04 '14 at 11:32
  • @Flovdis Do you mean I should cast everything to `std::string` like: `std::string s = (std::string)"apg -n" + (std::string)x + ...` – TN888 Jul 04 '14 at 11:33
  • @FinalContest Yes, this is clear to me. But this is horrible code! If he is using Qt, he should use a `QString` to combine all strings from the various sources, because at the end he needs a `QString` as result. Horrible code, it hurts my eyes and my heart... – Flovdis Jul 04 '14 at 11:34
  • @Ty221 Yes, declare a `QString result;` at the begin, then use e.g. `result += xxx` to add all parts. Or use the `.arg()` operators. Or you can use a `QTextStream`. – Flovdis Jul 04 '14 at 11:35
  • @Ty221 I posted an example how to assemble strings in Qt using the `.arg()` functions or using a `QTextStream`. Both methods are great is you are mixing a lot of different types. To use the `std::string` with a `.arg()` use the `.c_str()` method. – Flovdis Jul 04 '14 at 11:41
  • The problem is caused by first line and not but mixing with QString yet! – 4pie0 Jul 04 '14 at 11:52
  • @DavidHeffernan: I am impressed the question is not yet closed. It is too broad, asking several different things without a clear SSCCE, and to be honest each issue separately is already duplicate. Having that said, I was the only upvoter. ;) – László Papp Jul 04 '14 at 11:58

2 Answers2

1

Use QString as primary string type:

QString result = QString("apg -q -n %1 -x %2 -y %3").arg(n).arg(x).arg(y);

Or use a QTextStream to assemble everything.

QString result;
QTextStream ts(&result);
ts << "apg -q -n " << n << " -x " << x;

To use std::string with .arg():

std::string x = "xxx";
QString result = QString("xxx -x %1").arg(x.c_str());

See the Qt documentation for details about QString and QTextStream.

Flovdis
  • 2,945
  • 26
  • 49
  • The problem is not with using std::string. It can be used properly. – László Papp Jul 04 '14 at 11:41
  • @FinalContest Sure you **can** use `std::string` but he is writing a Qt application, so he **should not** use `std::string` to assemble the result. He should use `QString` instead. – Flovdis Jul 04 '14 at 11:44
  • why is that? Because you like QString? He may not prefer something else than your preference? – László Papp Jul 04 '14 at 11:48
  • In fact, I also prefer std::string instead of QString at times since it is less bloated, not requiring a Qt application instance, and so on. – László Papp Jul 04 '14 at 11:58
  • The only problem with `std::string` is that it's next to useless in real life. It looks good only on paper, but when you actually need to use it to manipulate real strings, you end up reimplementing everything that `QString` provides and `std::string` misses. Heck, a lot of the stuff provided by `QChar` is not there either. It's kinda important when you write something more than academic exercises... – Kuba hasn't forgotten Monica Jul 04 '14 at 15:15
  • 1
    Or, to rephrase: I don't know what problems `std::string` is intending to solve, but it sure as heck isn't anything that I actually need. Whereas `QString`'s API seems to be somewhat directed by what people need in real life, not when sitting on a standardization committee :) – Kuba hasn't forgotten Monica Jul 04 '14 at 15:17
-1

Substitute this statement

std::string wyniki = "apg -q -n " + n + " -m " + m + " -x " + sx + " -a " + a;

for

std::string wyniki = std::string( "apg -q -n " ) + n + " -m " + m + " -x " + sx + " -a " + a;

provided that all operands have type either char[] or char *.

Otherwise if for example variable n has type int then write

std::string wyniki = "apg -q -n " + std::to_string( n ) + " -m " + m + " -x " + sx + " -a " + a;

Take into account that only objects of type std::string have overloaded operator +.

After you updated your post then your "bad line" has to look as

std::string wyniki = "apg -q -n " + std::to_string( n ) + " -m " + 
                     std::to_string( m ) + " -x " + 
                     std::to_string( sx ) + " -a " + std::to_string( a );

If QString has an implicit conversion operator to const char * then instead of

if(a==1)wyniki += " -M " + mode; //badline 

you have to write

if(a==1)wyniki += std::string( " -M " ) + mode; 
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • This is wrong an answer because the int is still there without conversion. – László Papp Jul 04 '14 at 11:33
  • Yes, after my post, sure, and I even appreciate that... However, even then, this answer does not address all the bad lines, and everything in the beginning is non-working red-herring. – László Papp Jul 04 '14 at 11:48
  • @Ty221 See my post. I showed how to change the "bad line", – Vlad from Moscow Jul 04 '14 at 13:13
  • 1) Yes, I know. I provided the solution before, too, but decided to remove. :) 2) I do not like `std::`, sorry. It is silly to repeat that many times. 3) I do not think this question should deserve any help. 4) You still do not address all the "bad" lines. – László Papp Jul 04 '14 at 14:45