Pointer Practice Ideas?

Hey guys I'm new to pointers and don't quite understand the concept fully yet but decided to try a program out to get better at it.
In my code I don't understand why it is printing the very last name twice from my txt file? There is only 1 Cameron so I don't know how or why it is printing the last name twice.
Also how to compare the users input to determine if it is in my array? How would I code that? I have a list of 14 names to be exact in my txt file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
#include <fstream>
#include <stdlib.h>

using namespace std;

const int SIZE = 14;
string ptr_array[SIZE];

int *ptr = NULL;
void getIndex(string[], int, string, int *);

int main()
{
    //Cameron prints twice?? Why
    ifstream name;
    name.open("studentName.txt");
    string name1;
    while(!name.eof()){
      name >> name1;
    int *ptr = new int[SIZE];
    for(int i = 0; i < SIZE; i++){
        *(ptr + i) = i * i;
    }

    cout << name1 << endl;
    }

    getIndex(ptr_array,SIZE,name1,ptr);

    //free up memory
    delete [] ptr_array;

    name.close();
    return 0;
}


void getIndex(string studentArray[], int arraySize, string searchName, int *index){

    int SIZE = 14;
    string studentArr[SIZE];
    string searchN;
    int *indx;
    indx = NULL;

    //just need to know if user input
    //matches whats in the array, if so, do W/E
    cout << endl;
    cout << "Please enter a name or QUIT to exit:" << endl;
    while(searchN != "QUIT"){
        if(searchN == studentArr[SIZE]){ // how to compare the users input to tell if it is in the array?
        cin >> searchN;
        cout << "Index: " << &indx << endl;
    }else{
            cout << "Not found" << endl;
            cin >> searchN;
        }
    }

}
There are numerous things in your code that give me pause:

1) You dynamically-allocate an array of ints (stored in "ptr") for each while-loop iteration and you give each index a value (its index number squared) but the you don't do anything with this array of its indeces. Are you just practicing, or did you forget something?

2) You need a "delete[] ptr" call within the while loop, somewhere after the assignment to "new[]" otherwise when the while loop iterates again, you lose your handle to the old array, but it stays allocated and you get a memory leak.

3) Your "delete[] ptr_array" call need to go! As ptr_array was not dynamically allocated using new[], its in the static storage area (where all global variables are).

4) The reason the last name in your file prints twice is b/c your check for EOF occurs at the beggining of the loop. After the last name is read in with "name >> name1" (the file is at EOF, but no read past that was made, so the stream has not signaled its EOF state) it is printed on the console. The check in the while produces true, so another iteration occurs. This time "name >> name1" fails to read in a name, sets the EOF state in the stream, and "name1" still contains its previous contents ("Cameron") which is promptly printed again.

The solution is to check for EOF *after everytime* a name is read in. Altho some people dislike this stylistically, I prefer it because it involves less repeat code (having only 1 "name >> name1" statement in your while instead of 2, one in your while and one preceeding it), and is not *totally* unstructured b/c it simply means the condition driving the loop occurs in the middle of the loop, not at the beginning:

1
2
3
4
5
6
while(true) {  //Infinite loop?? Nonesense!
   name >> name1;
   if (!name)  //Since EOF is whats being tested could use "if (name.eof())" if preferred.
      break;
   cout << name1 << '\n';  //Avoid endl for a newline, it messes with cout's internal buffer and slows it down. Just pass a '\n' char instead.
}

Sorry, I only addressed half your question. To see if the user's input is in your array, you first need to edit the previous loop so the the names are stored 1-by-1 in your array, like this:

1
2
3
4
5
6
7
8
9
10
11
12
int currentIndex = 0;  //Array start at index 0.
while(true) {
   name >> name1;
   if (!name)
      break;
   if (currentIndex < SIZE)  //Just in case read in too many names, don't do undefined behavior and notify via error message.
      ptr_array[currentIndex] = name1;
   else
      cout << "\nERR: Array not large enough to store name '" << name1 << "'";
   cout << name1 << '\n';
   ++currentIndex;  //Nest iteration, use the next array element.
}


Then in your other function (which I found a little confusing and having some unneeded parameters) you'd pass "currentIndex" as 1 of the parameters b/c that would then equal the number of meaningful, used elements in your array.
Then examine each element in your array, and compare it to the sought-after name, if it matches, leave the loop, and you know you have the index you need. If go thru the entire array and don't find the name, your index-counter will be >= the number of iterations, and you can tell the user the name wasn't found. Something like:

1
2
3
4
5
6
7
8
9
10
int index;
for(index=0; index < numUsedArrayElements; ++index) {
   if (soughtAfterName == arrayOfNames[index])
      break;
}
//At this line, the loop is done, but was it b/c of the "index < ..." check produced false? Or because the "break" was reached? We need to find out...
if (index < numUsedArrayElements)  //The break wwas reached! otherwise the loop would have kept going if this is true...
   cout << "\nIndex for that name is: " << index;
else  //Break was not reached so name was never found...
   cout << "\nSorry, that name was not found.";


I've given you a lot, so see if you can put the missing pieces together from here yourself ;).
Topic archived. No new replies allowed.