I want to add a new line in this. This is my sample code:
ui->button->setText(" Tips " + "\n" + TipsCount );
This is the error it shows:
invalid operands of types 'const char [7]' and 'const char [2]' to binary 'operator+'
But when I add to label it gets appended!
ui->label->setText(name + "\n" + City );
Can someone please help me?
This is a very common problem in C++ (in general, not just QT).
Thanks to the magic of operator overloading, name + "\n" gets turned into a method call (couldn't say which one since you don't list the type). In other words, because one of the two things is an object with + overloaded it works.
However when you try to do "abc" + "de", it blows up. The reason is because the compiler attempts to add two arrays together. It doesn't understand that you mean concatenation, and tries to treat it as an arithmetic operation.
To correct this, wrap your string literals in the appropriate string object type (std::string or QString most likely).
Here is a little case study:
QString h = "Hello"; // works
QString w = "World"; // works too, of course
QString a = h + "World"; // works
QString b = "Hello" + w; // also works
QString c = "Hello" + "World"; // does not work
String literals in C++ (text in quotes) are not objects and don't have methods...just like numeric values aren't objects. To make a string start acting "object-like" it has to get wrapped up into an object. QString is one of those wrapping objects, as is the std::string in C++.
Yet the behavior you see in a and b show we're somehow able to add a string literal to an object. That comes from the fact that Qt has defined global operator overloads for both the case where the left operand is a QString with the right a const char*:
http://doc.qt.nokia.com/latest/qstring.html#operator-2b-24
...as well as the other case where the left is a const char* and the right is a QString:
http://doc.qt.nokia.com/latest/qstring.html#operator-2b-27
If those did not exist then you would have had to write:
QString a = h + QString("World");
QString b = QString("Hello") + w;
You could still do that if you want. In that case what you'll cause to run will be the addition overload for both operands as QString:
http://doc.qt.nokia.com/latest/qstring.html#operator-2b-24
But if even that didn't exist, you'd have to call a member function. For instance, append():
http://doc.qt.nokia.com/latest/qstring.html#append
In fact, you might notice that there's no overload for appending an integer to a string. (There's one for a char, however.) So if your TipsCount is an integer, you'll have to find some way of turning it into a QString. The static number() methods are one way.
http://doc.qt.nokia.com/latest/qstring.html#number
So you might find you need:
ui->button->setText(QString(" Tips ") + "\n" + QString::number(TipsCount));
Related
I am trying to print an integer alongside a string but it's not really working out and am getting confused.
int cmdSeries = 3;
Serial.println("Series : " + cmdSeries);// That's where the problem occur
In visual basic we used to do it this way:
Dim cmdSeries As Integer
Console.Writeline(""Series : {0}", cmdSeries)
So i've tried it with Serial.println but it returns this error :
call of overloaded 'println(const char [14], int&)' is ambiguous
Can anyone help my out, I want to achieve this without using any libraries and in a clean way.
There is a huge difference between Arduino String class and regular C-string.
The first one overloads addition operator, but there is almost excessive usage of dynamic memory. Mainly if you use something like:
String sth = String("blabla") + intVar + "something else" + floatVar;
Much better is just using:
Serial.print("Series : ");
Serial.println(cmdSeries);
Btw, this string literal resides in Flash and RAM memory, so if you want to force using flash only:
Serial.print(F("Series : "));
But it's for AVR based Arduinos only. This macro can save a lots of RAM, if you are using lots of literals.
EDIT:
Sometimes I use this:
template <class T> inline Print & operator<<(Print & p, const T & val) {
p.print(val);
return p;
}
// ...
Serial << F("Text ") << intVar << F("...") << "\n";
It prints each part separately, no concatenations or so.
Try this
int cmdSeries = 3;
Serial.println(String("Series : ") + cmdSeries);
I have custom(dynamic QString) for example something like this 123+555 and i need to get this after +.Also there can be something different then + (/,*,- etc.). My question is how to get part of string after some char.
Use the split function, which allows you to specify the separator and returns a list of the elements.
QString string("123+555");
QStringList listItems = string.split('+', QString::SkipEmptyParts);
QString finalString = listItems[1];
Alternatively, you can find by index the separating character location and use that with a call to right
Since you're usin Qt, you could try the class: QRegExp.
With such class you could write code like this:
// This code was not tested.
QRegExp rx("(\\d+)(\\+|\\-|\\*|/)(\\d+)"); // Be aware, I recommend you to read the link above in order to see how construct the proper regular expression.
int pos = rx.indexIn("23+344");
if (pos > -1) {
QString number_1 = rx.cap(1); // "23"
QString op = rx.cap(2); // "+"
QString number_2 = rx.cap(3); // "344"
// ...
}
This way you don't have to write code to check which of the characters(operators) "+, -, *, /" is present to then perform a split on the string depending on what character was found.
I want to overload the + operator for my mainwindow class(or any other class) for Qstring.
this is what I have done so far :
void operator+(QString a,QString b)
{
qDebug()<<"works";
}
but the thing is, the QString + operator is already overloaded(to concatenate, I guess).
so, if I use the above code, it results in ambiguity(both the signatures are same).
how do I override the actual function to my own function without making a new class to hold QString?
Try QString operator+(QString a,QString b). The return type of the overloaded function is QString, not void. The compiler cannot differ between two overloads only differ by return type.
How can i find a specific character in a QFile which has a text in it?
for example i have ' $5000 ' written somewhere in my file. in want to find the "$" sign so i will realize that I've reached the number.
I tried using QString QTextStream::read(qint64 maxlen) by putting 1 as the maxlen :
QFile myfile("myfile.txt");
myfile.open(QIODevice::ReadWrite | QIODevice::Text);
QTextStream myfile_stream(&myfile);
while(! myfile_stream.atEnd())
{
if( myfile_stream.read(1) == '$')
{
qDebug()<<"found";
break;
}
}
and i get "error: invalid conversion from 'char' to 'const char* "
i also tried using the operator[] but apparently it can't be used for files.
Read in a line at a time and search the text that you've read in
QTextStream stream(&myFile);
QString line;
do
{
line = stream.readLine();
if(line.contains("$"))
{
qDebug()<<"found";
break;
}
} while (!line.isNull());
The error message you've posted doesn't match the issue in your code. Possibly the error was caused by something else.
QTextStream::read returns QString. You can't compare QString and const char* directly, but operator[] can help:
QString s = stream.read(1);
if (s.count() == 1) {
if (s[0] == '$') {
//...
}
}
However reading a file by too small pieces will be very slow. If your file is small enough, you can read it all at once:
QString s = stream.readAll();
int index = s.indexOf('$');
If your file is large, it's better to read file by small chunks (1024 bytes for example) and calculate the index of found character using indexOf result and count of already read chunks.
a single char could be read with
QTextStream myfile_stream(&myfile);
QChar c;
while (!myfile_stream.atEnd())
myfile_stream >> c;
if (c == '$') {
...
}
myfile_stream.read(1) - this is not good practice, you should not read from file one byte at a time. Either read the entire file, or buffered/line by line if there is a risk for the file to be too big to fit in memory.
The error you get is because you compare a QString for equality with a character literal - needless to say that is not going to work as expected. A string is a string even if there is only one character in it. As advised - use either the [] operator or better off for reading - QString::at() const which is guaranteed to create no extra copy. You don't use it on the QFile, nor on the QTextStream, but on the QString that is returned from the read() method of the text stream targeted at the file.
Once you have the text in memory, you can either use the regular QString methods like indexOf() to search for the index of a contained character.
in want to find the "$" sign so i will realize that I've reached the
number.
It sounds to me that you're searching for the '$' symbol because you're more interested in the dollar value that follows it. In this case, I suggest reading the files line by line and running them through a QRegExp to extract any values you're looking for.
QRegExp dollarFind("\\$(\\d+)");
while(!myfile_stream.atEnd()){
QString line = myfile_stream.readLine();
if (dollarFind.exactMatch(line)){
QStringList dollars = dollarFind.capturedTexts();
qDebug() << "Dollar values found: " << dollars.join(", ");
}
}
I have a global variable that is a *char. My main function header reads as int main(int argc, char* argv[argc]){...}. These two lines of code have to remain the way they are. The first argument of my main function is a number of type *char, that I convert to a char using atoi(...);. I am basically changing the ASCII value to its corresponding character. Now I want to store this local variable character I have into the global variable that is a char pointer. I know the problem is related to allocation of memory, but I am not sure how to go about this.
My code:
char* delim;
int main(int argc, char* argv[argc])
{
char delimCharacter;
if (isdigit(*(argv[3])) == 0) delim = argv[3]; //you can pass in a character or its ascii value
else { //if the argument is a number, then the ascii value is taken
delimCharacter = atoi((argv[3]));
printf("%s\t,%c,\n", argv[3], delimCharacter);
//sprintf( delim, "%c", delimCharacter ); // a failed attempt to do this
*delim = delimCharacter;
//strncpy(delim, delimCharacter, 1); // another failed attempt to do this
}
//printf("%s\n",delim);
This yields a seg fault.
You need to verify you have got (at least) 3 arguments before you start using them.
if (argc < 4)
{
printf("Need 3 args");
exit(1);
}
Then you need to allocate some memory to put the character in.
delim = malloc(2);
// TODO: Should check the result of malloc before using it.
*delim = delimCharacter;
delim[1] = 0; // Need to NULL terminate char*
You're dereferencing an uninitialized pointer. delim never gets initialized when it goes into the else block.
char delim[] = ","; // anything really, as long as as it's one character string
...
delim[0] = delimCharacter;
In addition to your memory issue, I think you are confused about what atoi does. It parses a string representation of a number and returns the equivalent int value, e.g. "10000" => 10,000. I think that you think it will give you the ASCII value of a character, e.g. "A" =>65.
Since you have a char *, and you are (I think) assuming that it contains a single character, you could simply do this:
delimCharacter = *(argv[3]);
However, there really seems to be no need to use the intermediate step of assigning this value to a char variable at all. If the end goal is to have delim point to the char that is the delimiter, then it seems this is all you need to do:
delim = argv[3];
Not only does this remove unnecessary code, but it means you would no longer need to allocate additional memory for delim to point to.
I would also declare delim as a const char * since I assume there is no reason to change it.