-4

I'm getting a strange error when trying to iterate a Map of Vectors. I'm using the Stanford CS106B class libraries for this project and when I try to compile the code I get an error telling me that "itr has no member named 'first' "

I have tried searching for solutions to this problem and I have found many similar entries but the answers seem to mimic what I'm doing. I'm sure I'm missing something simple...

#include <iostream>
#include <fstream>
#include <string>
#include "console.h"
#include "simpio.h"  // for getLine
#include "strlib.h"
#include "vector.h"
#include "queue.h"
#include "map.h"
#include <iterator>
using namespace std;

void CountLetters(ifstream &filename) {
    int index=0;
    Vector<int> counts;
    for (int i=0; i<=26; i++) {
        counts.add(0);
    }
    char c;
    while (!filename.eof()) {
        c=filename.get();
        index=c-'a';
        if (index>=0 && index<26) {
            c=stringToChar(toLowerCase(charToString(c)));
            counts[index]++;
        }
    }
    for (int y=0; y<=26; y++) {
        cout << char('a'+y) << ": " << counts[y] << endl;
    }
    filename.close();
}

Map <string, Vector<char> > assembleSets (ifstream &in, int seed) {
    Map <string, Vector<char> > letterSets;
    char c;
    Vector<char> workingText;
    string letterSet;
    while(!in.eof()) {
        if (workingText.size()<seed) {  // Build the intial set of "seed" letters.
            c=in.get();
            workingText.add(c);
        }
        else {
            c=in.get();
            letterSet.clear();
            for (int i=0; i<workingText.size()-1; i++) {
                letterSet+=workingText[i];  // add the letter to the letter set.
                workingText[i]=workingText[i+1]; // move the letter down one in the vector (simulate queue).
            }
            letterSet+=workingText[seed-1];
            workingText[seed-1]=c;  // add the newwest letter to the workingText but do not add it to the letter set.

            // Check to see if the letter set exists already, if not, add it.
            if (!letterSets.containsKey(letterSet)) {
                Vector<char> blank;
                letterSets.add(letterSet,blank);
                letterSets[letterSet].add(c);
            }
            else {
            // Add the next character to the vector of characters for that letter set.
            letterSets[letterSet].add(c);
            }
        }
    }
    return letterSets;
}

int main() {
    ifstream in;
    int mSeed =0;


    while (true) {
        string fileName = getLine("Please enter a file name");

        in.open(fileName);
        if(in.fail()) cout << "Couldn't open file!" << endl;
        else break;
    }
    // CountLetters(in);



    while (true) {
        mSeed=getInteger("Enter a seed value: ");
        if (mSeed>0&&mSeed<=10) {
            break;
        } else {
            cout << "Please choose a value from 1 to 10." << endl;
        }
    }

    Map<string, Vector<char> > letterSets = assembleSets(in, mSeed);
    Map<string, Vector<char> > :: iterator itr;

    for (auto& it: letterSets) {
       string keys = (it.first);
       Vector<char> values = it.second;
    }
    return 0;
}

Any help would be fantastic! I'm really scratching my head.

Eeets
  • 1
  • 2
  • What is `Map` actually? – πάντα ῥεῖ Jul 07 '16 at 14:32
  • 2
    Smells like Homework ? https://communitystandards.stanford.edu/student-conduct-process/honor-code-and-fundamental-standard – Pogrindis Jul 07 '16 at 14:34
  • It certainly is... but it's on iTunes U as a free course. I'm a structural engineer learning object oriented programming as a hobby. – Eeets Jul 07 '16 at 14:38
  • `Map` and `Vector` do not exist in C++. `std::map` and `std::vector` do exist in the standard. So we don't know what `iter` is referring to in the context of these non-standard classes. – PaulMcKenzie Jul 07 '16 at 14:42
  • `but it's on iTunes U as a free course.` -- So why this free course didn't just use the standard classes instead of home-made `Map` and `Vector` classes (unless you used the improper casing of such classes, i.e. lower-case `m` for map and lower-case `v` for vector). – PaulMcKenzie Jul 07 '16 at 14:43
  • Mandatory read: [Why is `iostream::eof` inside a loop condition considered wrong?](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – molbdnilo Jul 07 '16 at 14:50
  • It's literally the Stanford CS106B course... Full video lectures from 2008 with support files, old assignments, handouts and class libraries. Free means there is no support from the University and no tuition cost to the participant. I'm learning so if I have to revert to the std vector and map containers, I will. I was just hoping it was something simple. – Eeets Jul 07 '16 at 14:52
  • You still haven't shown us the details of `Map>::iterator`. If you don't know, then you can't guess at what members there are or how to access them. The iterator may have named the items "item1", "item2" as far as we know instead of "first" and "second". You should be giving us these details, and not us having to go to Stanford U. websites to tell you what they are. – PaulMcKenzie Jul 07 '16 at 14:53
  • A "Stanford Map" iterator *doesn't* have a member called `first` - it has no publicly accessible member variables at all. Dereferencing it gives you the key of the corresponding entry. – molbdnilo Jul 07 '16 at 14:57
  • Thanks Paul! That was exactly the insight I was missing. I foolishly didn't understand where iterator was coming from. I now see that in the map.h file there is code which dictates how the iterator works. I'm obviously pretty new at this... I was thinking that the iterator was just a standard thing - not dependent on the variable type. – Eeets Jul 07 '16 at 14:57
  • 1
    I wouldn't recommend to follow a course from 2008. C++ has changed *a lot* since then (notably with the standard C++11, which was finalized in 2011). Back then, vectors and maps where not part of the standard library, so that's why Stanford decided to roll their own. Nowadays using a proprietary container equivalent to one in the standard library would be a bad idea, unless there are very good reasons for it. Here the reason is simply that the course is old. My advice: find something else. Maybe you can try with Coursera, which has a good reputation. – Fabio says Reinstate Monica Jul 07 '16 at 15:32

1 Answers1

1

It simply means that Map<string, Vector<char> > :: iterator. Using std::map instead of Map and std::vector instead of Vector compiles correctly.

Check the implementation of your custom iterator.

Anyway i suggest you using the range-based syntax for this (if you use the C++ standard library):

for (auto& it : letterSets)
{
    string key = it.first;
    vector<char> values = it.second;
}
Mattia F.
  • 1,720
  • 11
  • 21
  • I appreciate the suggestion. I would prefer to use the class libraries if I can since I'm trying to follow along with code examples and the vector.h Stanford headers have functions like .add() for ease of use. I did try altering the code as you suggested although still using Map and Vector instead of the std equivalents. Still no luck... Same error. Is it possible I'm missing something in my include statements? – Eeets Jul 07 '16 at 14:44
  • Well check the documentation, I can't solve your problem without even seeing your code. – Mattia F. Jul 07 '16 at 14:45
  • @Eeets -- Your question and ultimate answer relies on what `iter` is in these classes. You didn't show us this. The only thing we have is to compare your classes with the standard classes, and the standard iterator class for map works correctly, as this answer demonstrates. – PaulMcKenzie Jul 07 '16 at 14:47
  • I have amended my original post to include the full code. It sounds like it's a problem with those classes however, and I'll just have to learn to use the standard classes instead. – Eeets Jul 07 '16 at 14:54
  • We need the definition of Map and Vector. – Mattia F. Jul 07 '16 at 14:55