2012-03-20 7 views
2

DirObjの時間/サイズでベクトルをソートしない理由を理解できません....私が苦労しているコードの関連部分はすぐ下にありますが、このプロジェクトの完全なコード(3ファイル)以下。std :: sortはコンパレータとして機能を使用していて、動作していませんか?

編集:私はおそらく、物事を動かすように見えるが、最終結果は順序付けされていないか逆順ではなく、私が並べ替えようとしているプロパティとは無関係のようだ。

関連部分:

sortBy() { 
    std::sort(v.begin(), v.end(), byTime); 
    std::cout << "Sorted by time:" << std::endl; 
    for (it = v.begin(); it != v.end(); ++it) { 
     std::cout << **it; 
    } 
    std::sort(v.begin(), v.end(), bySize); 
    std::cout << "Sorted by size:" << std::endl; 
    for (it = v.begin(); it != v.end(); ++it) { 
     std::cout << **it; 
     delete *it; 
    } 
} 

bool byTime(DirObj * x, DirObj * y) { 
    return (((x->getStat()).st_size) < ((y->getStat()).st_size)); 
} 

bool bySize(DirObj * x, DirObj * y) { 
    return (((x->getStat()).st_atime) < ((y->getStat()).st_atime)); 
} 

Traversal.cpp

/* A file traversal program for the Unix filesystem. */ 
/* Allows the user to select one of the following options: 
    depth-first-order (stack) 
    breadth-first-order (queue) 
    Sort by size */ 

#include <iostream> 
#include <stdio.h> 
#include <string> 
#include <string.h> 
#include <sys/types.h> 
#include <dirent.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include "DirObj.h" 
#include <queue> 
#include <stack> 
#include <vector> 
#include <algorithm> 

void printUsage(); 
void breadthFirst(const std::string); 
void depthFirstR(const std::string); 
void depthFirstNR(const std::string); 
void sortBy(const std::string); 
bool byTime(DirObj *, DirObj *); 
bool bySize(DirObj *, DirObj *); 

int main(int argc, char **argv) { 
    std::string buffer; 
    int cnt; 

    /* input validation, check for too few arguments */ 
    if (argc < 3) { 
     printUsage(); 
     return 1; 
    } 

    /* get directory pathname */ 
    buffer = argv[2]; 
    buffer.append("/"); 


    /* check for options */ 
    if (strcmp(argv[1], "-a") == 0) { 
     breadthFirst(buffer); 
     std::cout << std::endl << "Recursive depth-first traversal of " << buffer << ":" << std::endl; 
     depthFirstR(buffer); 
     depthFirstNR(buffer); 
     sortBy(buffer); 
    } 
    else if (strcmp(argv[1], "-b") == 0) { 
     breadthFirst(buffer); 
    } 
    else if (strcmp(argv[1], "-d") == 0) { 
     std::cout << std::endl << "Recursive depth-first traversal of " << buffer << ":" << std::endl; 
     depthFirstR(buffer); 
     depthFirstNR(buffer); 
    } 
    else if (strcmp(argv[1], "-s") == 0) { 
     sortBy(buffer); 
    } 
    else { 
     printUsage(); 
     return 1; 
    } 

    std::cout << std::endl << "DONE. All requested traversals were successful." << std::endl; 

    return 0; 
} 

void printUsage() { 
     printf("Usage: ./dirTraverse <mode> <directory pathname>\n"); 
     printf(" Modes:\n"); 
     printf(" -a All traversals\n"); 
     printf(" -b Breadth-first\n"); 
     printf(" -d Depth-first\n"); 
     printf(" -s Sort by size\n"); 
     printf(" -t Sort by time\n"); 
     return; 
} 

/* uses a queue */ 
void breadthFirst(const std::string b) { 
    std::cout << std::endl << "Breadth-first traversal of " << b << ":" << std::endl; 

    struct dirent *d; 
    DIR *dir; 
    struct stat stat_b; 
    std::string buffer; 
    buffer = b; 

    std::queue<DirObj *> q; 
    DirObj * o; 

    /* open the initial directory */ 
    dir = opendir(buffer.c_str()); 
    if (!dir) { 
     std::cout << "Could not open " << buffer << "." << std::endl; 
    } 
    else { 
     /* push all directory entries onto queue */ 
     while ((d = readdir(dir))) { 
      q.push(new DirObj(d, buffer)); 
     } 
     // closedir(dir); 
    } 

    /* dequeue each directory entry and print */ 
    while (!q.empty()) { 
     o = q.front(); 
     q.pop(); 
     std::cout << *o; 
     d = o->getEntry(); 
     stat_b = o->getStat(); 
     /* if the entry is a directory (but not . or ..) */ 
     if (S_ISDIR(stat_b.st_mode) && (strcmp(d->d_name, "..") != 0) && (strcmp(d->d_name, ".") != 0)) { 
      buffer = o->getPath(); 
      buffer.append(d->d_name); 
      /* open directory */ 
      dir = opendir(buffer.c_str()); 
      if (!dir) { 
       std::cout << "Could not open " << buffer << "." << std::endl; 
      } 
      else { 
       /* push all directory entries onto queue */ 
       buffer.append("/"); 
       while ((d = readdir(dir))) { 
        q.push(new DirObj(d, buffer)); 
       } 
       // closedir(dir); 
      } 

     } 
     delete o; 

    } 
} 

/* recursive, works, very basic */ 
void depthFirstR(const std::string b) {  
    struct dirent *d; 
    DIR *dir; 
    struct stat stat_b; 
    std::string buffer = b; 
    int l = buffer.length(); 

    /* open initial directory */ 
    dir = opendir(buffer.c_str()); 
    if (!dir) { 
     std::cout << "Could not open " << buffer << "." << std::endl; 
    } 
    else { 
     /* while there are directory entries, read the next one and print it */ 
     while ((d = readdir(dir))) { 
      buffer.append(d->d_name); 
      stat(buffer.c_str(), &stat_b); 
      std::cout << buffer << " : {inode=" << d->d_ino << ", size=" << stat_b.st_size << ", time=" << stat_b.st_atime << "}" << std::endl; 
      /* if the directory entry is a directory, recursively traverse it */ 
      if (S_ISDIR(stat_b.st_mode) && (strcmp(d->d_name, "..") != 0) && (strcmp(d->d_name, ".") != 0)) { 
       buffer.append("/"); 
       depthFirstR(buffer); 
      } 
      buffer = buffer.substr(0, l); 
     } 
     // closedir(dir); 
    } 
} 

/* non-recursive, uses an explicit stack of DirObj to keep track of paths associated with dirents */ 
void depthFirstNR(const std::string b) { 
    std::cout << std::endl << "Non-recursive depth-first traversal of " << b << ":" << std::endl; 

    struct dirent *d; 
    DIR *dir; 
    struct stat stat_b; 
    std::string buffer = b; 

    DirObj *o; 
    std::stack<DirObj *> s;  

    /* open the initial directory */ 
    dir = opendir(buffer.c_str()); 
    if (!dir) { 
     std::cout << "Could not open " << buffer << "." << std::endl; 
    } 
    else { 
     /* push all directory entries onto stack */ 
     while ((d = readdir(dir))) { 
      s.push(new DirObj(d, buffer)); 
     } 
     // closedir(dir); 
    } 

    /* pop each directory entry off stack and print */ 
    while (!s.empty()) { 
     o = s.top(); 
     s.pop(); 
     std::cout << *o; 
     d = o->getEntry(); 
     stat_b = o->getStat(); 
     /* if the entry is a directory (but not . or ..) */ 
     if (S_ISDIR(stat_b.st_mode) && (strcmp(d->d_name, "..") != 0) && (strcmp(d->d_name, ".") != 0)) { 
      /* open directory */ 
      buffer = o->getPath(); 
      buffer.append(d->d_name); 
      dir = opendir(buffer.c_str()); 
      if (!dir) { 
       std::cout << "Could not open " << buffer << "." << std::endl; 
      } 
      else { 
       /* push all directory entries onto stack */ 
       buffer.append("/"); 
       while ((d = readdir(dir))) { 
        s.push(new DirObj(d, buffer)); 
       } 
       // closedir(dir); 
      } 
     } 
     delete o; 
    } 
} 


void sortBy(const std::string b) { 
    std::cout << std::endl << "Sorted by size/time traversal of " << b << ":" << std::endl; 

    struct dirent *d; 
    DIR *dir; 
    struct stat stat_b; 
    std::string buffer = b; 

    DirObj * o; 
    std::stack<DirObj *> s; 
    std::vector<DirObj *> v; 

    /* open the initial directory */ 
    dir = opendir(buffer.c_str()); 
    if (!dir) { 
     std::cout << "Could not open " << buffer << "." << std::endl; 
    } 
    else { 
     /* push all directory entries onto stack */ 
     while ((d = readdir(dir))) { 
      s.push(new DirObj(d, buffer)); 
     } 
     // closedir(dir); 
    } 

    /* pop each directory entry off stack and print */ 
    while (!s.empty()) { 
     o = s.top(); 
     s.pop(); 
     v.push_back(o); 
     d = o->getEntry(); 
     stat_b = o->getStat(); 
     /* if the entry is a directory (but not . or ..) */ 
     if (S_ISDIR(stat_b.st_mode) && (strcmp(d->d_name, "..") != 0) && (strcmp(d->d_name, ".") != 0)) { 
      /* open directory */ 
      buffer = o->getPath(); 
      buffer.append(d->d_name); 
      dir = opendir(buffer.c_str()); 
      if (!dir) { 
       std::cout << "Could not open " << buffer << "." << std::endl; 
      } 
      else { 
       /* push all directory entries onto stack */ 
       buffer.append("/"); 
       while ((d = readdir(dir))) { 
        s.push(new DirObj(d, buffer)); 
       } 
       // closedir(dir); 
      } 
     } 
    } 

    std::vector<DirObj *>::iterator it; 
    std::sort(v.begin(), v.end(), byTime); 
    std::cout << "Sorted by time:" << std::endl; 
    for (it = v.begin(); it != v.end(); ++it) { 
     std::cout << **it; 
    } 
    std::sort(v.begin(), v.end(), bySize); 
    std::cout << "Sorted by size:" << std::endl; 
    for (it = v.begin(); it != v.end(); ++it) { 
     std::cout << **it; 
     delete *it; 
    } 
} 

bool byTime(DirObj * x, DirObj * y) { 
    return (((x->getStat()).st_size) < ((y->getStat()).st_size)); 
} 

bool bySize(DirObj * x, DirObj * y) { 
    return (((x->getStat()).st_atime) < ((y->getStat()).st_atime)); 
} 

DirObj.h

#include <string> 
    #include <iostream> 
    #include <sys/types.h> 
    #include <dirent.h> 
    #include <sys/stat.h> 
    #include <unistd.h> 

class DirObj { 

    friend std::ostream& operator<< (std::ostream &out, DirObj &obj); 

    private: 
     dirent * entry; 
     std::string path; 
     struct stat stat_b; 

    public: 
     DirObj(dirent * e, const std::string p); 
     DirObj(); 
     ~DirObj(); 
     DirObj(const DirObj &rhs); 
     DirObj& operator=(const DirObj &rhs); 
     std::string getPath() const; 
     dirent * getEntry() const; 
     struct stat getStat() const; 
}; 

DirObj.cpp

#include "DirObj.h" 

DirObj::DirObj(dirent * e = 0, const std::string p = "\0") { 
    entry = e; 
    path = p; 
    std::string buffer = path; 
    buffer.append(entry->d_name); 
    stat(buffer.c_str(), &stat_b); 
} 

DirObj::DirObj() { 
    entry = 0; 
    path = "\0"; 
} 

DirObj::~DirObj() { 

} 

DirObj::DirObj(const DirObj &rhs) { 
    this->entry = rhs.entry; 
    this->path = rhs.path; 
    this->stat_b = rhs.stat_b; 
} 

DirObj& DirObj::operator=(const DirObj &rhs) { 
    this->entry = rhs.entry; 
    this->path = rhs.path; 
    this->stat_b = rhs.stat_b; 
    return *this; 
} 

std::string DirObj::getPath() const { 
    return path; 
} 

dirent * DirObj::getEntry() const { 
    return entry; 
} 

struct stat DirObj::getStat() const { 
    return stat_b; 
} 

std::ostream& operator<< (std::ostream &out, DirObj &obj) { 
    out << obj.path << (obj.entry)->d_name << ": {inode=" << (obj.entry)->d_ino << ", size=" << (obj.stat_b).st_size << ", time=" << (obj.stat_b).st_atime << "}" << std::endl; 
    return out; 
} 
+1

あなたはあなたが混入両方の機能 'byTime'と' bySize'(の名前を交換する必要があります下に実際の問題領域にコードを蒸留し、例えば、出力と入力 – 111111

+3

を提供していただけますソート順のプロパティ)。 – hochl

+0

'struct stat getStat()const;'は 'stat getStat()const;'でなければなりません。 –

答えて

1

両方の関数の名前をByTimeとBySize(プロパティを混合して並べ替え)に置き換える必要があります。固定バージョン:

bool byTime(DirObj * x, DirObj * y) { 
    return (((x->getStat()).st_atime) < ((y->getStat()).st_atime)); 
} 

bool bySize(DirObj * x, DirObj * y) { 
    return (((x->getStat()).st_size) < ((y->getStat()).st_size)); 
} 
+0

それをキャッチするためにありがとう!私は今、かなり馬鹿だと感じています... –

関連する問題