I don't know how to explain this in debug

  • Thread starter Thread starter yungman
  • Start date Start date
  • Tags Tags
    Explain
Click For Summary
The discussion revolves around a debugging issue in a C++ program that adds names to a vector and sorts them. The user encounters a problem with an if statement at line 51, where string comparisons are incorrectly evaluating due to comparing memory addresses instead of the actual string values. It is clarified that to compare C-style strings, the `strcmp()` function from the `<cstring>` library should be used instead of direct comparisons. The conversation also touches on programming design methods, with a preference for writing steps in plain English over traditional flowcharts for clarity. Ultimately, the user learns the importance of understanding how C-style strings work in memory, leading to a resolution of their issue.
  • #31
yungman said:
Thanks

I cannot find a better word than "sort"! Yes, the vector is sorted, just want to insert the new element into it. I read the name binary search and tree in later chapters. I just decided to be adventurous and do it. I don't want to wait and wait until I learn all the tools before attempt doing something. That's part of the adventure!

thanks
What you're doing is an insertion sort with a binary search instead of iterative comparisons to determine the insertion point ##-## there's a C++ example here: https://www.geeksforgeeks.org/binary-insertion-sort/
 
  • Like
Likes yungman
Technology news on Phys.org
  • #32
sysprog said:
What you're doing is an insertion sort with a binary search instead of iterative comparisons to determine the insertion point ##-## there's a C++ example here: https://www.geeksforgeeks.org/binary-insertion-sort/
Actually this is a lot easier than what I am doing. The tricky part is to start the vector with no element. If you look at the subscripts S, M and E in my word file, you'll see they are different when you first push_back into an empty file. As it turn out, I don't even have to create the second page for 6 and 7 elements, you can see the trend in the first page already. That's the reason I separate into 3 different cases, case0, case1 and case2 and have to be treated differently.

insertion .jpg
 
  • #33
yungman said:
The tricky part is to start the vector with no element.
That's not usually tricky, the implementation should go something like this:
[code title=pseudocode]
function insertElement(element, array)
// Set the lowest and highest points possible for insertion.
low = 0;
high = array.length;
// Note if the array is empty high == low == 0 so the loop
// is not executed and the element is inserted at array[0]
while high > low
midpoint = floor((high + low) / 2)
...
[/code]
 
  • #34
pbuk said:
That's not usually tricky, the implementation should go something like this:
[code title=pseudocode]
function insertElement(element, array)
// Set the lowest and highest points possible for insertion.
low = 0;
high = array.length;
// Note if the array is empty high == low == 0 so the loop
// is not executed and the element is inserted at array[0]
while high > low
midpoint = floor((high + low) / 2)
...
[/code]
high = array.length - 1. It will be negative if there is no element in the array. It is this kind of small little things that are tricky. You can have the program running correctly until you hit these kind of potholes. It was to the point that I decided to stop and wrote out the chart in the word file. Then it became clear. I literally deleted all the former work and start over new and finished in one day with the chart.
 
  • #35
I finally finish to adding name, show certain range of names, delete name. I am sure the add_sort the last name is correct, I played with the first name , display and delete, so far, it works. But I want to play with it more to confirm. FINALLY, I can go back to my original Directory project and store all the names in a file so I can call them up the next time I run the program to do adding, delete. This is my final program:
C++:
#include <iostream>
#include <cstring>
#include <vector>
#include <iomanip>
using namespace std;
const static int nameLen = 25, phoneLen = 12;
struct Directory { char lastName[nameLen]; char firstName[nameLen];    char phone[phoneLen]; int element; };
std::vector<Directory>DirV;
Directory Dir;
void addName(int&);
void sort_firstName(int&);
void showRange(char[]);
void deleteName(int);
int main()
{
    int newName, index = 0, compSize, numDelete;
    char more, displayAll, choice;
    char selName[25];
    cout << " Welcome to the directory program. You can add name, contact informations and\n";
    cout << " it will store in a file. You can display selected names and choose to delete\n";
    cout << " anyone you want.\n\n";
    do {
         cout << " Please enter 'a' to add names, 's' to dispay complete list. 'r' to show \n";
         cout << " range of names around a name. 'd' for delete a specific name. 'q' to quit.\n\n";
         cout << " Please enter what you want to do:  "; cin >> choice; cout << "\n\n";
         switch (choice)
           {
             case 'a': //Add new names and sort
               { do { cout << " Enter last name:  "; cin >> Dir.lastName;
                      //cout << " Enter first name:  "; cin >> Dir.firstName;
                      addName(newName);
                      sort_firstName(newName);
                      cout << " \n\nDo you want to enter another name?  "; cin >> more;
                    }while (tolower(more) == 'y');
                 break;
               };//End case 'a'
             case 's': //Display entire list of names and info
               { index = 0;
                 if(DirV.size() > 0)
                   { do { cout << "   Element #" << DirV[index].element <<
                          "]  is:   Last name: " << left << setw(10) << DirV[index].lastName <<
                          " first name: " << left << setw(10) << DirV[index].firstName << "\n\n";
                          index++;
                        } while (index < DirV.size()); break;
                    } else cout << " There is no name in the file.\n\n";
               };//End case 's'
             case 'r':
               { if (DirV.size() > 0)
                  { cout << " Enter the first 2 character of the last name to search.";
                    cin >> selName; cout << "\n\n";
                   showRange(selName);//Display range before and after the name initials.
                  }else cout << " There is no name in the file.\n\n";
                 break;
               };
             case 'd'://Delete a name.
               { showRange(selName);
                 cout << " Enter the Element# of the left to be deleted: ";
                 cin >> numDelete;
                 deleteName(numDelete);
                 break;
               };//End case 'd'
             case 'q':{ cout << " Are you sure you want to quit? ";
                        cin >> choice; cout << "\n\n";};
             default: cout << " Not a valid choice.\n";
           }//End switch
       } while(choice != tolower('q'));//End choice what to do

    return 0;
}//End main()

void addName(int& newName)
{ int size, selCase;
  DirV.push_back(Dir);//Push to next available element of DirV.
  size = DirV.size();// DirV[midPt].element = midPt; newName = midPt;
  int startPt = 0, endPt = size - 2, midPt = (endPt - startPt) / 2;
  if((size == 1)||((strcmp(DirV[endPt].lastName, Dir.lastName) <= 0) & (size >= 2)))
      selCase = 0;//Don't have to sort or anything, Dir is in last element already
//Case 0 for first entry when size = 1 OR when Dir.lastName is
// >= to last element of DirV(Dir.lastName >= DirV[endPt].lastName. 
  else
   {if((strcmp(Dir.lastName, DirV[startPt].lastName) <= 0) && (size > 1))
      selCase = 1;//If Dir smaller than DirV[0] AND (size >1)
    else
     { startPt = 0, endPt = size - 2; midPt = (endPt - startPt) / 2;
       do {  if (strcmp(Dir.lastName, DirV[midPt].lastName) <= 0)
                { endPt = midPt; midPt = (startPt + endPt) / 2; }
             else {startPt = midPt; midPt = (startPt + endPt) / 2; }
          }while (startPt != midPt);
       selCase = 2;
     }//else selCase = 2
   }//End if((strcmp(Dir.lastName, DirV[startPt].lastName) <= 0) && (size > 1))
  switch(selCase)
   //(size = 1)  AND  Dir.lastName => DirV[endPt].lastName
   {case 0: { DirV[size - 1].element = size - 1; newName = size - 1; break;}
    case 1://Dir.lastName <= DirV[0].lastName
        { int i;
          for(i = 1; i <= (size - 1); i++)
           { DirV[size - i] = DirV[size - i - 1];
             DirV[size - i].element = size - i;
             DirV[size - i - 1].element = size - i - 1;
           }//End for
          DirV[size - i] = Dir; newName = size - i;
          DirV[size - i].element = size - i;
          break;
        }//End case 1
    case 2:
        { int j;
          for(j = 1; j <= (size - endPt - 1); j++)
           { DirV[size - j] = DirV[size - j - 1];
             DirV[size - j].element = size - j;
             DirV[size - j - 1].element = size - j - 1;
           }
          DirV[size - j] = Dir; newName = size - j;
          DirV[size - j].element = size - j;
          break;
        }//end case 2
    }//End switch
}

void sort_firstName(int& newName)//DirV[newName] is the newly added name.
{   int beginLname = newName, endLname = newName;//start out all equal
    int bubbleDown, bubbleUp;
    Directory Temp;//Temporary structure variable to store structure Directory
    Temp = DirV[newName];
    bool doneUp = false, doneDown = false, moveUp = false;
    bubbleUp = newName; bubbleDown = newName;
    while ((bubbleUp > 0) & !doneUp)//Prevent bubbleUp going negative
       {if((strcmp(DirV[newName].lastName, DirV[newName - 1].lastName) == 0)
            & (strcmp(DirV[newName].firstName, DirV[newName - 1].firstName) < 0))
          {DirV[newName] = DirV[newName - 1]; DirV[newName].element = newName;
           DirV[newName - 1] = Temp; DirV[newName - 1].element = newName - 1;        
           newName--;bubbleUp--; moveUp = true;}     
        else (doneUp = true);
       }//END while((bubbleUp > 0)& !doneUp)
    if (moveUp == false)
      {while ((bubbleDown < (DirV.size()-1)) & !doneDown)
         { if((strcmp(DirV[newName].lastName, DirV[newName + 1].lastName) == 0)
             &(strcmp(DirV[newName].firstName, DirV[newName + 1].firstName) > 0))
            { DirV[newName] = DirV[newName + 1]; DirV[newName].element = newName;
              DirV[newName + 1] = Temp; DirV[newName + 1].element = newName + 1;
              newName++; bubbleDown++; } 
           else doneDown = true;
         }//END while (decrement < bubbleUp)
      }
}
void showRange(char selName[25])
{
    int size = DirV.size(), stpt = 0, edpt = size - 1;
    int mdpt = (stpt + edpt) / 2, index, comp;
    do //search to within range using 2 characters in selName
     {  comp = strncmp(selName, DirV[mdpt].lastName, 2);
        if (comp != 0) {if(comp > 0){stpt = mdpt; mdpt = (stpt + edpt)/2;}
        else {edpt = mdpt; mdpt = (stpt + edpt) / 2;}}
     } while ((comp != 0) && (stpt + 2 <= edpt));//Matching DirV[mdpt]
    for(index = -2; index <=3; index++)
      {if(((mdpt + index) >= 0) && ((mdpt + index) <= (size - 1)))
        { cout << "   Element #" << DirV[mdpt + index].element <<
        "]  is:   Last name: " << left << setw(10) << DirV[mdpt + index].lastName <<
        " first name: " << left << setw(10) << DirV[mdpt + index].firstName << "\n\n";}
      }//End for loop to display range of names if it is valid.
}//End showRange
void deleteName(int numDelete)
{   char sure;
    int edpt = DirV.size() - 1;
    cout << " Is this what you chose?\n";
    cout << "   Element #" << DirV[numDelete].element <<
          "]  is:   Last name: " << left << setw(10) << DirV[numDelete].lastName <<
          " first name: " << left << setw(10) << DirV[numDelete].firstName << "\n\n";
    cout << " Are you sure you want to delete this:\n\n"; cin >> sure;
    if (tolower(sure) == 'y')
    {
        for(int i = 0; i < (edpt - numDelete); i++)
        { DirV[numDelete + i] = DirV[numDelete + i + 1];
          DirV[numDelete + i].element = numDelete + i;}
        DirV.pop_back();
    }

}

It is getting very long. the next step on top of saving in file, I am going to break the program up using Class declaration and put a lot of these in the Specification and implementation file. I am even thinking about using two Specification files, one doing file management, the second one just add sort delete.

Thanks for all the help. It's educational. Working through the programs in the book is NOTHING like writing one of this program, one really find out what they actually learned. I had to kept going back to my notes, the book and online to find the correct ways to write the program.

Thanks
 
Last edited:
  • #36
jedishrfu said:
What was the value of midpoint?

When I look at failing statements like this in Java I look at these components:
- DirV - is it null or a bad-pointer?
- midPt - is the value within the range of 0<= midPt < length of the array ?
- DirV[midPt] - does the DirV[midPt] string look okay or is it not initialized or not what you expect?
- Dir - is it null or a bad-pointer?
- Dir.name - is the string what you expect?

I saw where you defined the DirV structure and used char name[namelen] but in your code I don't see any strcpy of Dir.name to that string? I also saw where you assign Dir to DirV but never allocate new space for Dir. This means that DirV will contain the pointer to Dir and since you didn't allocate new space every entry in DirV will point to the same Dir and will all get changed when you change the contents of Dir.

https://www.geeksforgeeks.org/strcpy-in-c-cpp/

Does that make sense?

Line 38 I see where you're doing a string compare which is really comparing pointers and not the strings.

http://www.cplusplus.com/reference/string/string/compare/
Definitely agree with jedishrfu - But I Would suggest you to read these articles ;

[Spam links deleted and spammer banned]
 
Last edited by a moderator:
  • #37
Thanks for sharing your insight here but since the thread is quite old I’m sure the OP has resolved his difficulties or moved to a new profession.

Time now to close this thread.
 

Similar threads

  • · Replies 75 ·
3
Replies
75
Views
6K
  • · Replies 30 ·
2
Replies
30
Views
4K
  • · Replies 32 ·
2
Replies
32
Views
3K
  • · Replies 66 ·
3
Replies
66
Views
5K
Replies
5
Views
2K
Replies
10
Views
2K
Replies
3
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 1 ·
Replies
1
Views
6K