QStringList "index out of range" - qt

I am trying to reverse the words within a QStringList. Below is the code up to now, but I keep on getting a "Index out of Range" error. From the error it would seem that I am trying to use data that is out of scope, but not able to figure out my problem.
QString reversed;
QStringList reversedlist;
QStringlist list = input.split(" ");
for (int i=0;i<list.length(); ++1)
reversedlist[i] = list[list.length() -1 -i];
reversed = reversedlist.join(" ");`
Thanks

As pointed out by #ThorngardSO, the reversedlist is initially empty, and you are trying to access the invalid index in your loop code. You should add values to the list using one of the following functions:
STL-compatible function push_back() (inserts value at the end of the list)
STL-compatible function push_front() (inserts value at the beginning of the list)
Qt function append() (Qt alternative for push_back)
Qt function prepend() (Qt alternative for push_front)
As you see, prepend() inserts the element at the beginning of the list, that is why it makes the reversing of the list very simple:
for (int i = 0; i < list.length(); ++i) {
reversedlist.prepend(list[i]);
}
Also, note that there is a typo in your loop: it should be ++i instead of ++1.

Your reversedList is initially empty. You have to actually append the items, like this:
reversedlist.push_back (list[list.length () - 1 - i]);
Naturally, trying to access non-existing items via reversedList[i] does not work and throws the index-out-out-range error.

You got the index out of range as there is no sting inside the QStringList reversedlist. So when your code reach the line reversedlist[0], it throw the "index out of range" error. And you can read the value using [0] and cant assign.
if you want to assign the value to a particular index of the QStringList.
QString reversed;
QStringList reversedlist;
QString input="123 456 789 000";
QStringList list = input.split(" ");
for (int i=0;i<list.length(); ++i){
//value to particular index
reversedlist.insert(i,list[list.length() -1 -i]);
}
reversed = reversedlist.join(" ");
qDebug() << reversed;

Related

char array variable name want to use in variable in Arduino IDE

i created char array
char Jan1[] = "1,2,3,4";
char Jan2[] = "5,7,3,4";
char Jan3[] = "10,9,3,4";`
the above char arrays i want to use it as shown below in for loop each time it will iterate and print, print is an example i am processing this string further in code, but it is giving error. if instead of yy i use Jan1 then it is printing properly. what is the other way i can use yy as to get print char array as string.
for(int i=1;i<=2;i++)
{
char yy[4];
sprintf(yy,"Jan%d",i);
String presentMonth = String(yy);
Serial.print(presntMonth);
}
So by the comments it seems that what you want is to print the contents of the JanX variable based on an index variable.
Missunderstanding
First of all you need to understand the difference between strings as datatypes and variable names. The former are ways to represent a sequence of characters (used mainly, but not only, to display output messages to any sort of output like a file, a console etc..). The latter are names that you use while coding and they can be whatever you want but they will never appear in the final program.
This for instance creates a String (datatype) named hello which contains the sequence of characters h e l l o.
String hello = "Hello";
Nothing prevents me to assign goodbye to it:
hello = "Goodbye"
Serial.print(hello); // This will print "Goodbye"
In general (apart from very hacky ways) you can't retrieve the name of the variable from your program and have them ready in your executable.
Issue
char Jan1[] = {'1','2','3'};
String yy = "Jan1"
Serial.print(yy); // This will print "Jan1"
To print the items in Jan1 you need to iterate through the values.
void printItems(char* s,int N){
for ( i = 0; i<N; i++ )
{ Serial.print(s[i]); }
}
Since Arduino provides the String class, however, it would be better to do this:
String Jan1 = "1,2,3,4";
Serial.print(Jan1); // This iterates under the hood, takes care of the length, and all the good stuff.
Solution
You want to do something a little more advanced, you want to point to a particular string based on a variable, then print the content of the retrieved string.
I can think of two ways for doing so: by using an list of strings or via a hashmap.
List of strings
String list[] = {"1,2,3,4" , "4,5,6,7", ... };
for(int i = 0; i < sizeof(list)/sizeof(String) ; i++ ){
Serial.print(list[i])
}
Hashmap
The reason I am thinking about this is because you want a string as the "index" that let's you lookup the string, so you can "search" by name. The easiest and quickest method I can think of is to declare an array of structs string_name;string_content and use strcmp to iterate through the array of structs until the needed one is found.
typedef struct{ String name; String content;} element_t;
element_t dict[] = { {"Jan1","1,2,3,4"} , {"Jan2","2,3,4,5"} ... }'
// Note this is not even close to perfect (for instance lacks check if key does not exists)
String lookup(element_t DICT, int DICT_SIZE, String key){
// Iterate through the elements, use strcmp to retrieve it
for(int i = 0; i < DICT_SIZE ; i++ ){
if(strcmp(DICT[i].name,key) {
return DICT[i].content;
}
}
}
// Now create the key, as in your code, and then lookup.
for(int i=1;i<=2;i++)
{
char yy[4];
sprintf(yy,"Jan%d",i);
String presentMonth = lookup(dict,dict_size,yy);
Serial.print(presntMonth);
}

Add String from textEdit to a QStack

I am trying to capture the contents from textEdit and add it to a QStack. The content I am splitting so to be able to reverse the order of the sentence captured. I already have that part covered, but I want to be able to convert from QStringList to be pushed to the QStack. This is what I have:
void notepad::on_actionReversed_Text_triggered()
{
QString unreversed = ui->textEdit->toPlainText();
QStringList ready = unreversed.split(QRegExp("(\\s|\\n|\\r)+"), QString::SkipEmptyParts);
QStack<QString> stack;
stack.push(ready);
QString result;
while (!stack.isEmpty())
{
result += stack.pop();
ui->textEdit->setText(result);
}
}
QStack::push only takes objects of it's template type.
i.e. In your case you must push QString's onto the QStack<QString>, and not a list.
So, iterate the list of strings pushing each one in turn.
foreach (const QString &str, ready) {
stack.push(str);
}
Something else that is wrong is that you are updating textEdit inside the for loop. You actually want to build up the string in the loop and afterwards update the text.
QString result;
while (!stack.isEmpty()) {
result += stack.pop();
}
ui->textEdit->setText(result);
An alternate answer could be to do away with the stack and just iterate the QStringList ready in reverse order to build up result string.

Qt QMap<int, MyClass> ignores insert command

I've a question that couldn't find anywhere. I have a QMap that's ignoring the QMap.insert(Key, Value) command. Here's the code:
//gets the selected problem index on the ProblemList
int selProblem = ui->tree_projects->currentItem()->data(0, Qt::UserRole).toInt();
//creates a new problem, sets its values and then replaces the old one on the ProblemsList variable
ProblemSets nProblem;
if(!problemsList.isEmpty()) //problemsList is an attribute of MainWindow
nProblem = problemsList.value(selProblem);
// some data collection that has been omitted because isn't important
// temporary maps that will carry the modifications
QMap<int, QString> nResName, nResType;
//data insertion into the maps
//these are fine
nResName.insert(fIdx, results_model->data(results_model->index(fIdx, 0)).toString());
nResType.insert(fIdx, results_model->data(results_model->index(fIdx, 1)).toString());
//replaces the old maps with the new ones
nProblem.SetProbResultsNames(nResName);
nProblem.SetProbResultsTypes(nResType);
//replaces the old problem with the new one
problemsList.insert(selProblem, nProblem); //this is the line that's doing nothing
}
That last line appears to be doing nothing! I've even tried to use
problemsList.remove(selProblem);
problemList.insert(selProblem, nProblem);
but got a similar result: the map not being inserted at the index selProblem. It got inserted, but with an outdated value - the same one of the deleted index -. I've checked on Debug and all the indexes and variables are correct, but when the .insert hits, nothing happens.
The most awkward thing is that this code is a copy/paste that I made from another method that I'm using that does similar thing, just changing the variable names, but that one works.
EDIT 1: This is the contents of nProblem, selProb and problemsList.value(selProblem)
Just before the Line:
problemsList.insert(selProblem, nProblem);
selProb: 0
nProblem:
ProbResultsNames: "NewRow0"
ProbResultsType: "Real"
problemsList.value(selProblem):
ProbResultsNames: non-existent
ProbResultsType: non-existent
After the line
problemsList.insert(selProblem, nProblem);
selProb: 0
nProblem:
ProbResultsNames: "NewRow0"
ProbResultsType: "Real"
problemsList.value(selProblem):
ProbResultsNames: non-existent
ProbResultsType: non-existent
EDIT 2:
class ProblemSets
{
public:
ProblemSets();
virtual ~ProblemSets();
ProblemSets(const ProblemSets& other);
ProblemSets& operator=(const ProblemSets& other);
//I hid getters and setters to avoid pollution on the post
private:
int index;
bool usingBenchmark;
QString functionSelected;
QString info;
QMap<int, QString> probVars_name, probVars_type, probResultsNames, probResultsTypes;
QMap<int, float> probVars_min, probVars_max;
QMap<int, int> probVars_stpSize, probVars_stp;
int varsNumber; // holds how many vars has been created, just for display purposes
int resNumber; // holds how many results has been created, just for display purposes
};
A simple test proves that QMap works as expected:
QMap<int, QString> mm;
mm.insert(1, "Test1");
qDebug() << mm[1]; // "Test1"
mm.remove(1);
qDebug() << mm[1]; // "" (default constructed value)
mm.insert(1, "Test2");
qDebug() << mm[1]; // "Test2"
Which means that the problem lies in your code.
This statement itself is highly suspicious:
That last line appears to be doing nothing!
Because then you go on to say that the map still contains the "old value". But you removed that key, so if the insert() method didn't work, you shouldn't be getting the old value, but a default constructed value.
Which means that the problem is most likely that nProblem has the same value as the one that is previously associated to that key in the map. The map works, you values are likely wrong.
Found the issue! I didn't have both the variables declared on the copy method of the ProblemSets class.
Solved simply adding them to the copy method
MainWindow::ProblemSets::ProblemSets(const ProblemSets& other)
{
// copy
index = other.index;
usingBenchmark = other.usingBenchmark;
functionSelected = other.functionSelected;
info = other.info;
probVars_name = other.probVars_name;
probVars_type = other.probVars_type;
probVars_min = other.probVars_min;
probVars_max = other.probVars_max;
probVars_stpSize = other.probVars_stpSize;
probVars_stp = other.probVars_stp;
//here
probResultsNames = other.probResultsNames;
probResultsTypes = other.probResultsTypes;
//
varsNumber = other.varsNumber;
resNumber = other.resNumber;
}
I had this issue before with the std::vector class, and that's why I suspected that could be that. Thanks to everyone that helped!

QList<QString> to QString.arg()

I have the following QString:
QString funcProxy = "executeProxy(\"%1\", \"%2\", \"%3\")";
The data for each on is in:
QList<QString> listProxy;
How would I go about adding the data in listProxy to funcProxy using the arg() method?
funcProxy.arg(??);
Thanks
Regarding the answer from #owacoder, you do not actually need the replace function, the following should work correclty:
for (int i = 0; i < listProxy.size(); ++i) {
funcProxy = funcProxy.arg(listProxy.at(i));
}
Why you ask: From the documentation on QString::arg()
Returns a copy of this string with the lowest numbered place marker replaced by string
Thus it replaces the lowest number with the string in the arg call. First iteration contains %1, %2 and %3, so it replaces %1. Next iteration contains %2 and %3, thus replaces %2.
Alternatively if you have control over funcProxy you can do the following given you can change your list to a QStringList:
QString funcProxy = "executeProxy(\"%1\")";
QStringList listProxy{"a", "b", "c"};
funcProxy = funcProxy.arg(listProxy.join("\", \""));
If you know you'll have exactly 3 elements in your list, you can do this:
funcProxy.arg(listProxy.at(0)).arg(listProxy.at(1)).arg(listProxy.at(2));
Otherwise, you could use this:
for (int i = 0; i < listProxy.size(); ++i)
funcProxy.replace(QString("%%1").arg(i+1), listProxy.at(i));

vector data check

hi a have a function that reads from a text file line by line each line I do some operations on it substitute a string..etc
then I push_back that line into a vector
this is my class in Parser.h
class Parser
{// start class
public:
vector<const char*> patterns;
Parser();
~Parser();
void RuleParser(const char *TextFileName); // this is the function that takes the file name
private:
};// end class
segment from function RuleParser
std::ifstream ifs(TextFileName);
while (!ifs.eof())
{
.
.modification code
.
patterns.push_back((buildString).c_str()); //buildString is the modified line
cout << buildString << endl;
}
but when I try to check out if the data in the vector is correct it output totally different data.
I even put a cout after the push_back to check it's integrty but I found buildString is correct... thats the data each time being pushed ... what I am doing wrong.
here is the loop I use to see if my data correct.
for (int i = 0;i < patterns.size() ;i++)
{
cout << patterns.at(i) << endl;
}
Well patterns is the collection of pointers so you end up push_back'ing a pointer to the same buildString in each iteration of the loop, instead of push_back'ing the string contents. Then when buildString changes in next iteration of the loop, the pointer becomes invalid but it still remains in patterns - not good
I suggest you declare patterns as:
vector<std::string> patterns;
This way when you do:
patterns.push_back(buildString.c_str())
the contents of the string will be copied instead of the pointer, and remain valid througout.

Resources