Like Tree1Likes

bool operator< issues

This is a discussion on bool operator< issues within the C++ Programming forums, part of the General Programming Boards category; Heh, well, William Putnam: what is your current code?...

  1. #16
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,650
    Heh, well, William Putnam: what is your current code?
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  2. #17
    Registered User
    Join Date
    Sep 2012
    Posts
    32
    I'm usually not too cool with posting my code online because I fear that someone could take the whole thing and try to pass it as their own. But at this point, I'm going to have to take a risk on it. So I'm going to post it now, and when the problem's solved, I'm going to delete it. Here goes:

    The entire assignment is a database program called trippy that creates .dat files containing the contents of a directory and their relevant information, as well as whether or not they have been modified recently. Our professor is assigning different parts over the next few weeks. She gives out the instructions in PDFs that tell you how to do basically everything: what to declare and how, what to do with the variables, what functions are good to use, etc. She leaves a few gaps for us to fill in, but of course that adds a challenge for the assignment.

    Last week I got a controller class up and running to read and [semi-]process arguments. This week I'm doing what she calls "the heart of the program." I'm supposed to create headers and c++ files for the directory entry (based off the dirent struct), the status variables, and the functions to handle them. So far, I'm 13 files into this overall project. I'll try to post them all below.

    A few disclaimers before I start. "tools.hpp" refers to the "toolkit" I'm given for the class that includes all the [usually] necessary header files as well as custom functions such as banner(), fatal(), bye(), etc. "using namespace std" has also been declared here (inb4 you f'ing idiot, because I'm not up for that argument right now). I've added all the extra required headers to it.

    Also, I'm posting my code as is, which means I haven't had the time to go through it to make everything look stylish and add comments. I'll clear up anything confusing if I need to, but because you guys know what you're doing, I'm not totally embarassed over my code being seen.

    Here's the code. When you see //*, you've reached the end of the file.

    Code:
    //file: direntry.hpp
    //Author: William Putnam
    //Last Updated: 9.26.2013
    
    #ifndef direntry_hpp
    #define direntry_hpp
    #include "tools.hpp"
    
    //dirent is defined exactly as in the instructions
    class direntry : public dirent{
        
    public:
        direntry(){};
        ~direntry();
        void print(ostream& out);
        
    };
    #endif
    
    //*
    
    //file: direntry.cpp
    //Author: William Putnam
    //Last Updated: 9.26.2013
    
    #include "direntry.hpp"
    
    void direntry::print(ostream& out){
        out << "File type: " << setw(30) << d_type << endl
            << "Inode #: " << setw(30) << d_ino << endl
            << "Name: " << setw(30) << d_name << endl;
    }
    
    //*
    
    //file: stats.hpp
    //Author: William Putnam
    //Last Updated: 9.26.2013
    
    #include "direntry.hpp"
    
    //stat is defined exactly as in the instructions
    class stats : public stat{
        
    public:
        stats();
        virtual ~stats();
        void print(ostream& out);
        int getInode(){ return st_ino;};
        int getMode(){ return st_mode;};
        int getLink(){ return st_nlink;};
        int getUID(){ return st_uid;};
        int getGID(){ return st_gid;};
        int getMTime(){ return st_mtimespec.tv_sec;};
        int getCTime(){ return st_ctimespec.tv_sec;};
        
    };
    
    //*
    
    //file: stats.cpp
    //Author: William Putnam
    //Last Updated: 9.26.2013
    
    #include "stats.hpp"
    
    stats::print(ostream& out){
        out << "Inode: " << setw(30) << st_ino << endl
            << "Protection mode: " << setw(30) << st_mode << endl
            << "Hard link count: " << setw(30) << st_nlink << endl
            << "User ID: " << setw(30) << st_uid << endl
            << "Group ID: " << setw(30) << st_gid << endl
            << "Last Updated: " setw(30) << st_mtimespec << endl
            << "Last Status Change: " setw(30) << st_ctimespec << endl;
    }
    
    //*
    
    //file: fileData.hpp
    //Author: William Putnam
    //Last Updated: 9.26.2013
    
    #include "stats.hpp"
    
    class fileData{
        
    private:
        char directName[256], *directType;
        int inodeNum;
        //---------
        int statNode, statMode, statLink, statUID, statGID, statMTime, statCTime;
        //---------
        char SHA1[20];
        
    public:
        fileData(direntry d, stats s);
        ~fileData();
    //WARNING: ERRORS STEM FROM THIS NEXT LINE!!!!!!!!!!!!
        bool operator<(const fileData& f) const { return strcmp(directName, f.directName) < 0;}
        void print(ostream& out);
        void serialize(ostream& out);
        
    };
    
    //*
    
    //file: fileData.cpp
    //Author: William Putnam
    //Last Updated: 9.26.2013
    
    #include "fileData.hpp"
    
    fileData::fileData(direntry d, stats s){
        fileData.directName = d.d_name;
        fileData.directType = d.d_type;
        fileData.inodeNum = d.d_ino;
        
        fileData.statNode = s.getInode();
        fileData.statMode = s.getMode();
        fileData.statLink = s.getLink();
        fileData.statUID = s.getUID();
        fileData.statGID = s.getGID();
        fileData.statMTime = s.getMTime();
        fileData.statCTime = s.getCTime();
        
        //SHA algorithm goes here
    }
    
    void fileData::print(ostream& out){
        out << directName << ", " << inodeNum << endl
            << statNode << "/" << statMode << ", " << statLink
            << ", " << statUID << "/" << statGID << ", "
            << statMTime << "/" << statCTime << endl;
    }
    
    void fileData::serialize(ostream& out){
        out << "File type: \t" << setw(30) << directType << endl
        << "Inode #: \t" << setw(30) << inodeNum << endl
        << "Name: \t" << setw(30) << directName << endl
        << "Inode: \t" << << statNode << endl
        << "Protection mode: \t" << setw(30) << statMode << endl
        << "Hard link count: \t" << setw(30) << statLink<< endl
        << "User ID: \t" << setw(30) << statUID << endl
        << "Group ID: \t" << setw(30) << statGID << endl
        << "Last Updated: \t" setw(30) << statMTime << endl
        << "Last Status Change: \t" setw(30) << statCTime << endl << "#\n";
    }
    
    //*
    
    //file: dirData.hpp
    //Author: William Putnam
    //Last Updated: 9.26.2013
    
    #include "fileData.hpp"
    
    class dirData{
        
    private:
        char* directoryName;
        int statNode, statMode, statLink, statUID, statGID, statMTime, statCTime;
        vector<fileData> fD;
        vector<string> subDir;
        int nFiles = 0, nDirs = 0;
        
    public:
        dirData(char* name, stats s);
        ~dirData();
        void print(ostream& out);
        void serialize(ostream& out);
        void pushfDVec(fileData f){ fD.push_back(f);}
        void printStrings(ostream& out){ for (int i = 0; i < nDirs; i++) out << subDir[i] << endl;};
        void serialFD(int i, ostream& out){ fD[i].serialize(out);}
        void sortFD(){ std::sort(fD.begin(), fD.end());}
        void sortStr(){ std::sort(subDir.begin(), subDir.end());}
        void incFiles(){ ++nFiles;};
        void incDirs(){ ++nDirs;};
        int getFileCnt(){ return nFiles;};
        
    };
    
    //*
    
    //file: dirData.cpp
    //Author: William Putnam
    //Last Updated: 9.26.2013
    
    #include "dirData.hpp"
    
    dirData::dirData(char* name, stats s){
        directoryName = name;
        fileData.statNode = s.getInode();
        fileData.statMode = s.getMode();
        fileData.statLink = s.getLink();
        fileData.statUID = s.getUID();
        fileData.statGID = s.getGID();
        fileData.statMTime = s.getMTime();
        fileData.statCTime = s.getCTime();
    }
    
    void dirData::print(ostream& out){
        out << directoryName << ", " << inodeNum << endl
            << statNode << "/" << statMode << ", " << statLink
            << ", " << statUID << "/" << statGID << ", "
            << statMTime << "/" << statCTime << endl;
    }
    
    void fileData::serialize(ostream& out){
        out << "File type: \t" << setw(30) << directType << endl
        << "Inode #: \t" << setw(30) << inodeNum << endl
        << "Name: \t" << setw(30) << directName << endl
        << "Inode: \t" << << statNode << endl
        << "Protection mode: \t" << setw(30) << statMode << endl
        << "Hard link count: \t" << setw(30) << statLink<< endl
        << "User ID: \t" << setw(30) << statUID << endl
        << "Group ID: \t" << setw(30) << statGID << endl
        << "Last Updated: \t" setw(30) << statMTime << endl
        << "Last Status Change: \t" setw(30) << statCTime << endl << "#\n";
    }
    
    //*
    //file: controller.hpp
    //Author: William Putnam
    //Last Updated: 9.24.2013
    
    #include "dirData.hpp"
    
    class controller{
        
    private:
        char *dbFile = NULL, *reportFile = NULL, *rootPath = NULL, *dirName = NULL;
        bool c = false, d = false, h = false, o = false, r = false,
            u = false, v = false;
        int argDiag = 0;
        bool lvl[4] = {false, false, false, false};
        dirData* currentStats = NULL;
     
    public:
        controller(){};
        ~controller(){};
        void run(int argc, char* argv[]);
        void decodeLine(int argc, char* argv[]);
        void printReport(int argc, char* argv[]);
        void processDir(char* directoryName);
        void processLevel(char* currentName);
        void cSwitch();
        void dSwitch();
        void hSwitch();
        void oSwitch();
        void rSwitch();
        void uSwitch();
        void vSwitch(int getArg);
        void noArg(){ cout << "Missing an argument. Can't process.\n"; exit(1);};
        void extraArg(){ cout << "Argument overflow. Can't process.\n"; exit(1);};
        
    };
    
    //*
    
    //file: controller.cpp
    //Author: William Putnam
    //Last Updated: 9.24.2013
    
    #include "controller.hpp"
    
    void controller::run(int argc, char* argv[]){
        decodeLine(argc, argv);
        printReport(argc, argv);
        processDir(rootPath);
    }
    //---------------------------------------------------------------------------
    void controller::decodeLine(int argc, char* argv[]){
        
        int getArg = 0, index = 0, cnt = 0;
        extern int opterr;
        static struct option argOpts[] = {
            {"database", required_argument, 0, 'D'},
            {"output", required_argument, 0, 'o'},
            {"help", no_argument, 0, 'h'},
            {"create", no_argument, 0, 'C'},
            {"update", no_argument, 0, 'U'},
            {"verify", required_argument, 0, 'V'},
            {"recur", no_argument, 0, 'r'},
            {0,0,0,0}};
            opterr = 0;                     //don't print out non-args
    //NOTE: required arguments are stored in optarg
        
        while (getArg != -1){
            getArg = getopt_long(argc, argv, "D:o:hCUV:r", argOpts, &index);
            switch(getArg){
                case 'C': {cSwitch(); ++cnt; break;}             //create database
                case 'D': {dSwitch(); ++cnt; break;}             //database name
                case 'h': {hSwitch(); ++cnt; break;}             //help
                case 'o': {oSwitch(); ++cnt; break;}             //output file
                case 'r': {rSwitch(); ++cnt; break;}             //recursive
                case 'U': {uSwitch(); ++cnt; break;}             //update
                case 'V': {vSwitch(getArg); ++cnt; break;}       //verify
            }
        }
        ++cnt;
        if (cnt == argc) noArg();
        else if (cnt == argc-2) extraArg();
        
        rootPath = argv[cnt];
        dirName = strchr(rootPath, '/');
        
        if (!v){                                //set default diag to 5
            lvl[0] = true;
            lvl[2] = true;
            argDiag = 5;
        }
        if (!d) dbFile = strdup("trippy.dat");
        if (!reportFile) reportFile = strdup("trippy.dat");
    }
    //---------------------------------------------------------------------------
    void controller::printReport(int argc, char* argv[]){
        
        for (int i = 0; i < argc; ++i) cout << argv[i] << " ";
        cout << endl;
        
        cout << "Output file name: " << (reportFile? reportFile : "") << endl;
        cout << "Input file name: " << (dbFile? dbFile : "") << endl;
        cout << "Create Database? " << (c? "YES\n" : "NO\n");
        cout << "Update: " << (u? "YES\n" : "NO\n");
        cout << "Diagnostic level: " << argDiag << endl;
        cout << "Recursive? " << (r? "YES\n" : "NO\n");
        cout << "Directory: " << (rootPath? rootPath : "") << endl;
        
    }
    //---------------------------------------------------------------------------
    void controller::processDir(char* directoryName){
        ofstream rFile(reportFile);
        fstream dFile(dbFile, fstream::app);
        
        if (!rFile.is_open() || !dFile.is_open()){
            fatal("Error opening specified files.\n");
        }
        
        rFile << rootPath << endl;
        dFile << rootPath << endl;
        
        processLevel(directoryName);
    }
    //---------------------------------------------------------------------------
    void controller::processLevel(char* currentName){
        stats s;
        direntry d;
        DIR* dr = opendir(currentName);
        struct dirent* index;
        string str;
        
        currentStats = new dirData(currentName, s);
        fstream dB(rootPath, fstream::app);
        while (index != 0){
            index = readdir(dr);
            if (index->d_type != DT_REG && index->d_type != DT_DIR){}
            else {
                //malloc(d);
                if (index->d_type == DT_REG){
                    currentStats->pushfDVec(fileData(direntry(),s));
                    currentStats->incFiles();
                }
                else if (index->d_type == DT_DIR){
                    currentStats->pushfDVec(fileData(direntry(), s));
                    currentStats->incDirs();
                }
            }
        }
        closedir(dr);
        currentStats->sortFD();
        currentStats->sortStr();
        currentStats->serialize(dB);
        for (int i = 0; i < currentStats->getFileCnt(); i++)
            currentStats->serialFD(i, dB);
        currentStats->printStrings(dB);
        
        if (r){}                                        //for recursion (later)
            
        
    }
    //---------------------------------------------------------------------------
    void controller::cSwitch(){
        char contin = '\0';
        
        if (v || u){
            cerr << "Can't verify/update a database that doesn't exist.\n";
            exit(1);
        }
        else if (d){
            cout << "The file you specified will be overwritten.\n" <<
            "Type y to continue, n to exit.\n";
            while (contin != 'n' || contin != 'N'){
                cin >> contin;
                if (contin == 'y' || contin == 'Y') break;
                else if (contin == 'n' || contin == 'N'){
                    d = false; return;
                }
                else cout << "Invalid entry.\nType y to continue, n to exit.\n";
            }
        }
        else c = true;
    }
    //---------------------------------------------------------------------------
    void controller::dSwitch(){
        char contin = '\0';
        
        d = true;
        if (c){
            fstream dFile(optarg);
            if (dFile.is_open()){
                cout << "The file you specified will be overwritten.\n" <<
                "Type y to continue, n to exit.\n";
                while (contin != 'n' || contin != 'N'){
                    cin >> contin;
                    if (contin == 'y' || contin == 'Y') break;
                    else if (contin == 'n' || contin == 'N'){
                        d = false; return;
                    }
                    else cout << "Invalid entry.\nType y to continue, n to exit.\n";
                }
            }
            dbFile = optarg;
        }
        //implement stream here (later)
    }
    //---------------------------------------------------------------------------
    void controller::hSwitch(){
        h = true;
        cout << "HELP:" << endl << "-o[utput] specifies output file" <<
            endl << "-i[nput] specifies input file" <<
            endl << "-d[atabase] specifies file containing checkpoint database" <<
            endl << "-c[reate] specifies the creation of a new database file" <<
            endl << "-v[erify] determines the diagnostic level" <<
            endl << "-u[pdate] updates the database file" <<
            endl << "-r[ecursive] process the directories recursively\n";
        exit(1);
    }
    //---------------------------------------------------------------------------
    void controller::oSwitch(){
        o = true;
        reportFile = optarg;
    }
    //---------------------------------------------------------------------------
    void controller::rSwitch(){
        r = true;
    }
    //---------------------------------------------------------------------------
    void controller::uSwitch(){
        if (v || c){
            cerr << "Can't verify/update a database that doesn't exist.\n";
            exit(1);
        }
        else u = true;
    }
    //---------------------------------------------------------------------------
    void controller::vSwitch(int getArg){
        if (c){
            cerr << "Can't verify/update a database that doesn't exist.\n";
            exit(1);
        }
        v = true;
        getArg = strtol(optarg, NULL, 10);
        argDiag = getArg;
        for (int i = 0; i < 4; i++){
            getArg = getArg >> 1;
            if (!!(getArg & 1) == 0b1) lvl[i] = true;
        }
    }
    
    //*
    
    //file: main.cpp
    //Author: William Putnam
    //Last Updated: 9.24.2013
    
    #include "controller.hpp"
    
    int main(int argc, char* argv[]){
        
        banner();
        
        controller cont;
        
        cout << "a greeting comment" << endl;
        
        cont.run(argc, argv);
    
        bye();
        
    }
    As a bonus, if it helps, I'm going to include the actual line that she gave to us to use for the operator in one of her class examples:

    Code:
    bool operator < ( Direntry b ) { 
            return (strcmp(d_name, b.d_name ) < 0); 
        }
    
    /*19. This shows how to define the < operator for your class.   You will need to 
         define < for this class in order to use std::sort.   This definition will sort the file names in ascending alphabetical order.*/
    Okay, laserlight, you've reached the abyss. I leave my fate in your hands, as well as anyone else who can spot my issue. Godspeed.

  3. #18
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,650
    Okay, what's the current error message?
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #19
    Registered User
    Join Date
    Sep 2012
    Posts
    32
    Code:
    Williams-iMac:wputn1_P3 Desktop$ c++ -o trippy -Wall -std=c++11 *.cpp
    dirData.cpp:9:13: error: expected unqualified-id
        fileData.statNode = s.getInode();
                ^
    dirData.cpp:10:13: error: expected unqualified-id
        fileData.statMode = s.getMode();
                ^
    dirData.cpp:11:13: error: expected unqualified-id
        fileData.statLink = s.getLink();
                ^
    dirData.cpp:12:13: error: expected unqualified-id
        fileData.statUID = s.getUID();
                ^
    dirData.cpp:13:13: error: expected unqualified-id
        fileData.statGID = s.getGID();
                ^
    dirData.cpp:14:13: error: expected unqualified-id
        fileData.statMTime = s.getMTime();
                ^
    dirData.cpp:15:13: error: expected unqualified-id
        fileData.statCTime = s.getCTime();
                ^
    dirData.cpp:19:37: error: use of undeclared identifier 'inodeNum'
        out << directoryName << ", " << inodeNum << endl
                                        ^
    dirData.cpp:29:23: error: expected expression
        << "Inode: \t" << << statNode << endl
                          ^
    9 errors generated.

  5. #20
    Registered User
    Join Date
    Sep 2012
    Posts
    32
    That was from oogabooga's earlier suggestions. My first post indicates what I was getting before I started.

  6. #21
    Registered User
    Join Date
    May 2010
    Posts
    2,711
    One of the things I see wrong is that you're trying to use the assignment operator with a C-string:

    Code:
       
    fileData::fileData(direntry d, stats s){
        fileData.directName = d.d_name;
        fileData.directType = d.d_type;
        fileData.inodeNum = d.d_ino;
    Another issue I see is these variables are part of the class so they don't need the "fileData." in this member function.

    Code:
       
    fileData::fileData(direntry d, stats s){
        directName = d.d_name;
        directType = d.d_type;
        inodeNum = d.d_ino;
    Jim

  7. #22
    Registered User
    Join Date
    Sep 2012
    Posts
    32
    Thanks, Jim, for pointing that out. I've fixed the code as per your suggestions, and added inodeNum to fileData (forgot to do this earlier). I am now down to one error:
    Code:
    Williams-iMac:wputn1_P3 Desktop$ c++ -o trippy -Wall -std=c++11 *.cpp
    dirData.cpp:29:23: error: expected expression
        << "Inode: \t" << << statNode << endl
                          ^
    1 error generated.
    EDIT: I've fixed that error, too. But now I've hit a few different ones:
    Code:
    Williams-iMac:wputn1_P3 Desktop$ c++ -o trippy -Wall -std=c++11 *.cpp
    fileData.cpp:8:16: error: array type 'char [256]' is not assignable
        directName = d.d_name;
        ~~~~~~~~~~ ^
    fileData.cpp:9:16: error: assigning to 'char *' from incompatible type
          '__uint8_t' (aka 'unsigned char')
        directType = d.d_type;
                   ^ ~~~~~~~~
    2 errors generated.
    Last edited by William Putnam; 09-26-2013 at 10:32 PM.

  8. #23
    Registered User
    Join Date
    May 2010
    Posts
    2,711
    Well look closely at the error message, it's pointing out exactly where the error is located. You seem to be either missing something before the point indicated or you have too many <<.


    And don't forget you can't use the assignment operator with C-strings, you need to use strcpy().

    Jim

  9. #24
    Registered User
    Join Date
    Sep 2012
    Posts
    32
    I've narrowed down my issues to a manageable point now. I've learned a huge lesson from all of this: always check your copypastas between files. Thanks to everyone who helped out.

    P.S. laserlight, it's not letting me modify my code post. Could you please delete it for me, or give me the permissions? Thanks!

  10. #25
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,239
    Quote Originally Posted by William Putnam View Post
    I'm usually not too cool with posting my code online because I fear that someone could take the whole thing and try to pass it as their own.
    Why would anyone do that? And if they did, why would you care?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  11. #26
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,548
    Quote Originally Posted by William Putnam View Post
    P.S. laserlight, it's not letting me modify my code post. Could you please delete it for me, or give me the permissions? Thanks!
    Make a new one.
    And in case you don't know, everything posted here is public domain, basically, which means that it's here to stay. Your source code or replies aren't going to get deleted.
    Last edited by Elysia; 09-29-2013 at 12:14 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #27
    Registered User
    Join Date
    Oct 2006
    Posts
    2,370
    Quote Originally Posted by jimblumberg View Post
    And don't forget you can't use the assignment operator with C-strings, you need to use strcpy().
    or maybe just stop using C-strings altogether. std::string does with its overloaded operators what the str*() family of functions does for C-strings.
    Elysia likes this.
    Code:
    namespace life
    {
        const bool change = true;
    }

  13. #28
    Registered User
    Join Date
    Jun 2005
    Posts
    6,262
    Quote Originally Posted by brewbuck View Post
    Why would anyone do that? And if they did, why would you care?
    Some people like collecting code from people who can't distinguish between a type and a variable
    Right 98% of the time, and don't care about the other 3%.

Page 2 of 2 FirstFirst 12
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Overload the..bool operator..?
    By 39ster in forum C++ Programming
    Replies: 18
    Last Post: 11-26-2008, 05:24 AM
  2. BOOL bool ? unresolved external symbol
    By xwielder in forum C Programming
    Replies: 6
    Last Post: 05-20-2008, 08:39 AM
  3. How get bool's from std::vector<bool>
    By 6tr6tr in forum C++ Programming
    Replies: 6
    Last Post: 04-14-2008, 05:24 AM
  4. Script errors - bool unrecognized and struct issues
    By ulillillia in forum Windows Programming
    Replies: 10
    Last Post: 12-18-2006, 03:44 AM
  5. Interesting: bool != BOOL
    By lightatdawn in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 01-09-2002, 10:09 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21