This code takes a string from a dialog box , and compares it to data in a list,and if succesfull sets the selection on the element from list .
The problem i am having is with the if , it works if i only search the first element , if i try to search any other , it just ignore the if condition and goes till the end o the list .
void CMFC1Dlg::OnBnClickedButton6()
{
CString variable;
cautare.GetWindowTextA(variable);
variable = variable.MakeLower();
if(variable!="")
{
list<Contact*>::iterator seek;
bool flag = TRUE;
int i = 0 ;
while(flag)
{
seek = agenda.first_element();
if( ((CString)((*seek)->getLastName().c_str())).MakeLower() == variable ||
((CString)((*seek)->getFirstName().c_str())).MakeLower() == variable ||
((CString)((*seek)->getFirstAndLastName().c_str())).MakeLower() == variable ||
((CString)((*seek)->getLastAndFirstName().c_str())).MakeLower() == variable)
{
contactsVariable.SetCurSel(i);
this->OnLbnSelchangeList1();
flag=FALSE;
}
advance(seek,i);
i++;
if (i == agenda.list_size())
{
flag = FALSE;
}
}
}
else
MessageBox("No text on input ", "Error", MB_ICONERROR | MB_OK);
cautare.SetFocus();
cautare.SetWindowTextA("");
}
You are setting seek = agenda.first_element(); at the beginning of every iteration of the while loop. Move that statement outside the loop and it should work.
EDIT: You would also need to change the seek call to only seek 1, rather than i, since you're no longer throwing out the result of the previous seeks.
You should move seek = agenda.first_element(); out of the while loop.
Since you are iterating over a list of elements, why not use the begin() and end() method of the associated list. So you can iterate over each element and don't need to advance the iterator in each loop.
The code could look like this
list<Contract*>::iterator seek = agenda.begin();
while (flag && (seek != agenda.end())) {
// do the comparison
seek++;
}
You are only ever comparing the first element move advance(seek,i); like this:
while(flag)
{
seek = agenda.first_element();
advance(seek,i);
...
Related
The code is to read instructions from text file and print out graphic patterns. One is my function is not working properly. The function is to read the vectors of strings I've got from the file into structs.
Below is my output, and my second, third, and sixth graphs are wrong. It seems like the 2nd and 3rd vectors are not putting the correct row and column numbers; and the last one skipped "e" in the alphabetical order.
I tried to debug many times and still can't find the problem.
typedef struct Pattern{
int rowNum;
int colNum;
char token;
bool isTriangular;
bool isOuter;
}Pattern;
void CommandProcessing(vector<string>& , Pattern& );
int main()
{
for (int i = 0; i < command.size(); i++)
{
Pattern characters;
CommandProcessing(command[i], characters);
}
system("pause");
return 0;
}
void CommandProcessing(vector<string>& c1, Pattern& a1)
{
reverse(c1.begin(), c1.end());
string str=" ";
for (int j = 0; j < c1.size(); j++)
{
bool foundAlpha = find(c1.begin(), c1.end(), "alphabetical") != c1.end();
bool foundAll = find(c1.begin(), c1.end(), "all") != c1.end();
a1.isTriangular = find(c1.begin(), c1.end(), "triangular") != c1.end() ? true : false;
a1.isOuter = find(c1.begin(), c1.end(), "outer") != c1.end() ? true : false;
if (foundAlpha ==false && foundAll == false){
a1.token = '*';
}
//if (c1[0] == "go"){
else if (c1[j] == "rows"){
str = c1[++j];
a1.rowNum = atoi(str.c_str());
j--;
}
else if (c1[j] == "columns"){
str = c1[++j];
a1.colNum = atoi(str.c_str());
j--;
}
else if (c1[j] == "alphabetical")
a1.token = 0;
else if (c1[j] == "all"){
str = c1[--j];
a1.token = *str.c_str();
j++;
}
}
}
Before debugging (or posting) your code, you should try to make it cleaner. It contains many strange / unnecessary parts, making your code harder to understand (and resulting in the buggy behaviour you just described).
For example, you have an if in the beginning:
if (foundAlpha ==false && foundAll == false){
If there is no alpha and all command, this will be always true, for the entire length of your loop, and the other commands are all placed in else if statements. They won't be executed.
Because of this, in your second and third example, no commands will be read, except the isTriangular and isOuter flags.
Instead of a mixed structure like this, consider the following changes:
add a default constructor to your Pattern struct, initializing its members. For example if you initialize token to *, you can remove that if, and even the two bool variables required for it.
Do the parsing in one way, consistently - the easiest would be moving your triangular and outer bool to the same if structure as the others. (or if you really want to keep this find lookup, move them before the for loop - you only have to set them once!)
Do not modify your loop variable ever, it's an error magnet! Okay, there are some rare exceptions for this rule, but this is not one of them.
Instead of str = c1[++j];, and decrementing later, you could just write str = c1[j+1]
Also, are you sure you need that reverse? That makes your relative +/-1 indexing unclear. For example, the c1[j+1 is j-1 in the original command string.
About the last one: that's probably a bug in your outer printing code, which you didn't post.
This is the snippet of code that I'm puzzled about. I'm checking for how long an incoming string is. I've appended * in order to have a sentinel value to stop the while loop. Yet, I'm consistently getting a length value that is inclusive of the * and I don't understand why, since the while loop with the nested if ought to stop prior to the *. Can someone point out what I'm doing wrong and why I'm having this issue?
void conversion(string romanIn)
{
length=0;
romanIn.append("*");
while(item!="*")
{
if(item != "*")
{
item = romanIn[length];
length++;
}
cout<<item;
}
you are naturally going to get a +1 the first time through the loop because you aren't initializing the variable "item". Also make it a do while instead of a while loop.
Try this:
do
{
// This line moves out of the if statement
item = romanIn[length];
if(item != "*")
{
length++;
}
cout<<item;
}while(item!="*")
What is the initial value of item?
Let's assume it's 0. You enter the loop
item == 0 != marker, so you enter the if as well, and you say
item = romanIn[0], length++
If romanIn[0] == "*" you will exit the loop, but your length now says 1 which includes the marker
I'm attempting to compare two string arrays. Whenever I get to the while loop inside of the if statement, I get stuck in an infinite loop because even though I have an iterator inside of the loop, it doesn't increment. I have the cout<< finder; in the loop just to see what finder is at, and it never increments above zero. If anyone could help I'd really appreciate it.
if (memory[p] == "J")
{
if (is_number(memory[p+1]))
{
worker = atoi(memory[p+1].c_str());
p = worker;
continue;
}
else
{
int finder = 0;
while (memory[p+1] != Symtablelab[finder])
{
cout << finder;
finder = finder + 1;
}
if (memory[p+1] == Symtablelab[finder])
{
int k = Symtablepos[finder];
worker = atoi(memory[k].c_str());
p = worker;
continue;
}
}
}
You said finder never increments above zero. Does it print finder = 0 at all? If it does, it means
memory[p+1] = Symtablelab[1]
just after 1st iteration, so the while loop gets terminated and finder sticks at 1.
EDIT
If you say, it prints finder = 0 continuously inside the while statement, then probably you have if (memory[p] == "J") inside an outer for or while (looping) statement.
If it is continuously printing finder and it is 0, then I must ask if this whole code snippet you posted is enclosed in a while statement that you did not post. It makes absolutely no sense that the while loop included in the statement you posted would not be incrementing finder if it is the loop that gets stuck in an infinite loop.
Or the other possibility is that Symtablelab has overriden the '[' ']' operators. If neither of these things are true, that something incredibly wonky is going on.
I have a method in a class LinkRepository, I am checking for duplicate entries in the vector array Datalinks, which is a member of the class. I loop through all the elements in the array to check in the new entry Datalink* datalink already exist in the array. If so then don't add, just exit the loop.
void LinkRepository::SaveLink(Datalink* datalink) {
bool Exist = false;
for(vector<Datalink*>::iterator dl = Datalinks.begin(); dl != Datalinks.end(); ++dl)
{
if((strstr((*dl)->ParentID, datalink->ParentID) != NULL) && (strstr((*dl)->ChildID,datalink->ChildID) != NULL))
{
Exist = true;
dl = Datalinks.end();
}
}
if(!Exist)
{
Datalinks.push_back(datalink);
}
};
My program seems to crash on the next loop of the statement dl = Datalinks.end();
I have no idea why it is crashing?
Replace
dl = Datalinks.end();
With:
break;
To exit the loop
Here is a simple example to illustrate why your solution can't work:
int i = 0;
for (; i != 10; ++i)
{
i = 10;
}
This loop will never end because i will be incremented to 11 before comparison i != 10
It is crashing because first you set the iterator to Datalinks.end() and then, upon leaving this iteration, the for loop itself increments the iterator, making an invalid operation.
for(vector<Datalink*>::iterator dl = Datalinks.begin(); dl != Datalinks.end() && !Exist; ++dl)
{
if((strstr((*dl)->ParentID, datalink->ParentID) != NULL) && (strstr((*dl)->ChildID,datalink->ChildID) != NULL))
{
Exist = true;
}
}
Like everyone had said you are iterating one over. So, it's going into unwanted memory locations resulting in a seg fault eventually. You have to realize that the ++dl is happening at the end of the loop.
Also, using a break statement here is ridiculous. You already have a bool, make use of it.
Briefly, I am trying to write a routine that reads comma separated values from a file into a stl vector. This works fine. The values in the csv file might also be in double quotes so I have handled this too by trimming them. However, there is one problem where the values between the quotes might also have commas in them which are not to be treated as delimiters.
If I have a file containing the line
"test1","te,st2","test3","test4"
My file routine reads this into a vector as
"test1"
"te
st2"
"test3"
"test4"
I wrote a routine which I just called PostProcessing. This would go through the vector and correct this problem. It would take each element and check of the first value was a quote. If so it would remove it. It would then look for another quote at the end of the string. If it found one it would just remove it and move onto the next item. If it didn't find one, it would keep going through the vector merging all the following items together until it did find the next quote.
However, this works in merging "te and st2" together into element 2 (index 1) but when I try and erase the required element from the vector it must be failing as the resulting vector output is as follows:
test1
test2
st2"
test3
"test4"
Note also the last element has not been processed because I derement the size of the count but as the vector erase has failed the true count hasn't actually changed.
The PostProcessing code is below. What am I doing wrong?
bool MyClass::PostProcessing()
{
bool bRet = false;
int nCount = m_vecFields.size();
for (int x = 0; x < nCount; x++)
{
string sTemp = m_vecFields[x];
if (sTemp[0] == '"')
{
sTemp.erase(0,1);
if (sTemp[sTemp.size()-1] == '"')
{
sTemp.erase(sTemp.size()-1, 1);
m_vecFields[x] = sTemp;
}
else
{
// find next double quote and merge these vector items
int offset = 1;
bool bFound = false;
while (x+offset < nCount && !bFound)
{
sTemp = sTemp + m_vecFields[x+offset];
if (sTemp[sTemp.size()-1] == '"')
{
// found corresponding "
sTemp.erase(sTemp.size()-1,1);
bFound = true;
}
else
{
offset++;
}
}
if (bFound)
{
m_vecFields[x] = sTemp;
// now remove required items from vector
m_vecFields.erase(m_vecFields.begin()+x+1, m_vecFields.begin()+x+offset);
nCount -= offset;
}
}
}
}
return bRet;
}
Edit: I've spotted a couple of issues with the code which I will be correcting but they don't affect the question being asked.
m_vecFields.erase(m_vecFields.begin()+x+1, m_vecFields.begin()+x+offset);
This function takes a semi-closed interval, which means the "end" of the interval to erase should point one-past the last element to erase. In your case, it points to that element. Change the second argument to m_vecFields.begin()+x+offset+1.
x += offset;
Since you've just processed an item and deleted everything up to the next item, you shouldn't skip offset items here. The x++ from the loop will do just fine.