Determining length for an array allocation - c++

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

Related

deleting an item in cicular linked list

My program is supposed to do 3 operations:
Insert
Delete
Show on a circular linked list.
My problem is in the delete function. here is the code:
void c_list::del()
{
int num;
if(isempty())
cout<<"List is Empty!"<<endl;
else
{
node *temp1=first;
node *temp2=NULL;
cout<<"Enter the number that u want to DELETE:"<<endl;
cin>>num;
while(temp1->next!=first && temp1->info != num)
{
temp2=temp1;
temp1=temp1->next;
}
if(num != temp1->info )
cout<<"your number was not found in the list"<<endl;
else
{
if(temp2!=NULL)
{
temp2->next=temp1->next;
cout<<temp1->info<<" was deleted"<<endl;
}
else
{
first=temp1->next;
cout<<temp1->info<<"was deleted"<<endl;
}
}
}
system("pause");
}
Delete function is working in this way: user enters a number, the program searches that number & when it founds the number, removes it from the list.
Now the problem is that, when the user enters a number that does not exist in the list, the "App crash window" appears(I mean this window:Program is not responding), while I have a provided an error message for this case("your number was not found in the list")!!
Can u tell me what the problem is?
Your insert routine is not creating a circular list. When the list is empty and the initial item is inserted first == NULL. In this case your code leaves the list in a non-circular state. Because:
newitem->next=first;
if(first==NULL)
first=newitem;
At this point first->next == NULL, which should never be the case in a circular list. Your search code fails whenever the item to be found does not exist in the list. This is because it never cycles back around to the first node, since the list is not circular.
I think in your while loop you are reaching to the end of list and
after below line temp1 gets NULL.
temp1=temp1->next;
Then you are trying to read info attribute from null pointer and this causes error.
if(num != temp1->info )
I know you said it is circular list but i am not sure it is implemented correctly or not. My suggestion is just try to print temp1->info after while loop to be sure that correctness of list and your implementation.
Happen that, if you insert a number that is not in list, you have a loop in the first while.
So:
node* temp1 = first;
node* temp2 = 0;
while(temp1->next!=first && !temp2) {
if(temp1->info == num) {
/* save pointer and exit from while */
temp2 = temp1;
} else {
temp1 = temp1->next;
}
}
Then your code produce garbage because you never call a delete.
Most likely the problem is on the insert method, where maybe, you don't assign correcly pointers.
And then, why system("pause"); ? Take a look here.

Weird pointer issue...constructing BST using array of pointers

So I am trying to create a BST using an array of pointers. My algorithm is correct (tested a version that doesn't use pointers), but when using the below code, the following occurs:
If I add the first element, it is added to position 1 of the array.
If I add a second element, for some reason, position 1 of the array is overwritten to this element, and then the program continues (else part) and attempts to insert it again.
EG. (traced the program with a bunch of couts)
1. Call add(5, 1)
inserting 5 into position 1
position 1 is now 5
2. Call add(4, 1)
position 1 is now 4
moving right
inserting 4 into position 3
position 1 is now 4
...
template <typename Item> void ABTree<Item>::add(Item input, int index){
if (array[1]==0){
array[1] = &input;
size++;
}else{
if (input < *array[index]){
if (array[2*index] == 0){
array[2*index] = &input;
size++;
}else
add(input, 2*index);
}else{
if (array[(2*index)+1] == 0){
array[(2*index)+1] = &input;
size++;
}else
add(input, (2*index)+1);
}
}
There are a whole lotta troubles in the code you've provided.
Assigning address of the temporary variable is
inadmissible. The "input" variable ends up right after the add
function returns. Storing its address than is meaningless and leads
to almost inevitable crash. In particular, when you're adding second element to your array, those condition checks:
if (array[1]==0)
if (input < *array[index])
yields undefined result, and therefore undefined control flow.
I don't know type of the container you're using but I assume it to
be a kind of vector or even plain C array. If my guess is true, you
should perform a bounds check before accessing array's elements with
the index.
No reallocation of the memory accupied by the array is performed.
Or, alternatively, if you're using a constant size array, no check
is performed (see 2).
So, basing on the output, you've got the following sequence when adding second element:
On the check that head is empty - false;
On the check if (input < *array[index]) - false, since array[index] contains garbage, this is why "inserting 4 into position 3" despite we should add 4 to the position 2;
On the check if (array[(2*index)+1] == 0) - again false, since this element contains garbage too (am I right that you didn't initialize your array with zeros?);
So, recursive call to the add routine happens...
I altered the code to accept a pointer to the item to be inserted instead.
if (array[1]==0){
array[1] = input;
size++;
}else{
if (*input < *array[index]){
if (array[2*index] == 0){
array[2*index] = input;
size++;
}else
add(input, 2*index);
}else{
if (array[(2*index)+1] == 0){
array[(2*index)+1] = input;
size++;
}else
add(input, (2*index)+1);
}
}

Iterator inside of loop will not increment

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.

logic issue or something more?

My program simulates a video store. In my list there are multiple copies of some videos. If I try to rent a video and the first copy of that video in the list is already rented, my program fails to continue checking to see if the other copies are available (a film is available if custId is '0000'). Take a look at the text file from where the list gets its members for a better understanding of what i'm describing:
Could anyone take a look and let me know if they spot an issue? Any help is appreciated, thanks.
Code from main
try
{
int index = 0;
bool found = false;
while (!found)
{
if (strncmp(filmId,filmList.getAt(index).number,6) == 0 && strncmp("0000",filmList.getAt(index).rent_id,5) == 0)//If that film is rented by NO customer
{
found = true;//customer can rent it
strcpy(newItem.number,filmId);//copy filmId into newItem
filmList.retrieve(newItem);//copy the struct in our orderedList with the same filmId/copy into newItem
filmList.remove(newItem);//delete the struct with same filmId/copy as newItem from the orderedList
strcpy(newItem.rent_id,custId);//update info in
strcpy(newItem.rent_date,rentDate);// newItem to show
strcpy(newItem.return_date,dueDate);// that it has been rented
filmList.insert(newItem);//put NewItem into list, effectivily replacing the removed item.
cout << "Rent confirmed!" << endl;
}
else
{
if (strncmp(filmId,filmList.getAt(index).number,6) > 0 || strncmp("0000",filmList.getAt(index).rent_id,5) > 0)
{
++ index;
}
else
{
throw string ("Not in list");
}
}
}
}
catch (string s)
{
cout << "\n***Failure*** " << s << endl;
}
Let me know if more code is required from any other parts of the program.
Here's my best guess with the code provided.
Let's say we are looking up 101001Casablanca, therefore I'm assuming filmId = "101001Casablanca". Also, assume the 101001Casablanca is checked out to customer 0001. We are comparing the first 6 characters of filmId to filmList.getAt(index).number, which I'm going to assume is at the very least "101001". This passes, but since it is checked out the second condition fails.
In the else we check the same strings in the first condition and still get 0 returned from strncmp which is false. The second condition is also false since strncmp("0000", "0001", 5) is -1. Therefore we go to the final else which throws.
If you are only checking string equality with strncmp, remember that it can return -1, therefore check if equal or not equal to 0.

If condition , doesn't code execute code properly

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);
...