Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.53/47: Рейтинг темы: голосов - 47, средняя оценка - 4.53
599 / 237 / 69
Регистрация: 08.08.2015
Сообщений: 1,637
1

Работа stat+dirent в цикле

22.10.2015, 13:25. Показов 9589. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день!
Наверно голову уже всем пробил этими функциями но все же спрошу!

Код:

C++
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <iostream>
#include <stdio.h>
#include <string>
#include <iterator>
#include <vector>
#include <fstream>
 
using namespace std;
/*  Расширения для хранения
 *  Distrib Mac :   dmg, pkg
 *  Distrib Win :   exe, bat, cmd
 *  Media       :   avi, mkv, mov, mp3, ipg
 *  Sundry      :   rar, zip, ect...
*/
struct MyFiles
{
    int number;        //№ по порядку
    string NameFiles;  //собственно имя
    string Type;       //расширение нужно для последующей сортировки
    int status;        //Отметка об удачном копировании
    string Comment;    //коментарии для логирования
    int qwer;
};
MyFiles mf;
vector<MyFiles> v;
struct stat buf;
char Vibor;
const char FTarget2[27]="/Users/mesteriis/Downloads";
//const char FTarget2[36]="/Users/mesteriis/Downloads/uTorrent";
 
void GetDIR(const char *Target)
{
    DIR *dir = opendir(Target);
    if(dir)
    {
    struct dirent *ent;
        while((ent = readdir(dir)) != NULL)
        {
        ++mf.number;
        string tmp=ent->d_name;
        auto temp=ent->d_name;
        auto mp4dir=stat(temp, &buf);           //проблема тут
        int rez=buf.st_mode &S_IFMT;            //Проблема тут
        //Отсеиваем мусор
        auto dotPos = tmp.find('.');
        if ((dotPos + 2) >= tmp.size())
        {
            mf.NameFiles="DEL";
            mf.Type="DEL";
            mf.Comment=tmp;
            v.push_back(mf);
            continue;
        }
        if (rez>32760)
        {
            auto extPos= tmp.size()-4;
            auto eolPos =  tmp.find('\n');
            mf.NameFiles=tmp.substr(0, extPos);
            mf.Type=tmp.substr(mf.NameFiles.size()+1, eolPos);
            mf.qwer=rez;
            v.push_back(mf);
            continue;
        } else
        {
            mf.NameFiles=tmp;
            mf.Type="DIR";
            v.push_back(mf);
            continue;
        }
        }
    }else std::cout << "Error opening directory\n";
 
 
 
}
 
int main()
{
GetDIR(FTarget2);
    cout << "Размер очереди на копирование = " <<v.size()<< " объектов" << endl;
    cout << "Печатаем: \n";
       for (unsigned long i=0; i<v.size(); ++i)
       {
      cout <<"# "<<v[i].number<< "\t Name "<<v[i].NameFiles<<" Type "<< v[i].Type <<" sys "<< v[i].qwer <<endl;
       }
    cout << "Удаленные обьекты:\n";
    for (unsigned long i=0; i<v.size(); ++i)
    {
    if (v[i].Type=="DEL") cout << v[i].Comment<< v[i].qwer << endl;
    }
    cout << "____________________\n";
    auto Ldir=stat("/Users/mesteriis/Downloads/uTorrent", &buf);
    int rez=buf.st_mode &S_IFMT;
    cout << "/Users/mesteriis/Downloads/uTorrent" << rez<< endl;
 
    return 0;
}
Комментарии:

Функция открывает и читает директорию с файлами, для того чтобы отличить файл от директории использую stat в моей системе ответ stat на файл =16384 на папку 32768 (Хотя в описании другие значения, но не концептуально потому что пробывал на большом количестве объектов суть е меняется), так вот в теории все хорошо, но на практике как только первый раз stat получил путь к файлу/папке он его не меняет. в чем может быть трабла я уже мозг сломал((((

Вот вывод:
Bash
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
Размер очереди на копирование = 19 объектов
Печатаем: 
# 1  Name DEL Type DEL sys 0
# 2  Name DEL Type DEL sys 0
# 3  Name $RECYCLE.BIN Type DIR sys 0
# 4  Name .DS_S Type ore sys 32768
# 5  Name .local Type zed sys 32768
# 6  Name 2-NDFL_obrazec-2013 Type xls sys 32768
# 7  Name 90baafe7206a5f39f3816ea867768045 Type jpg sys 32768
# 8  Name Adguard release Type dmg sys 32768
# 9  Name All_DnD3_5_Indexes Type rar sys 32768
# 10     Name boost_1_ Type 9_0 sys 32768
# 11     Name CodeBlocks Type app sys 32768
# 12     Name ecl Type pse sys 32768
# 13     Name eclipse-cpp-helios-macosx-cocoa-x86_64 Type tar sys 32768
# 14     Name json-ma Type ter sys 32768
# 15     Name MMB_1611_B6340-12-НДФЛ Type xls sys 32768
# 16     Name qt-unified-mac-x64-2022-online Type dmg sys 32768
# 17     Name uTor Type ent sys 32768     <-------- строчка из примера
# 18     Name vk Type com sys 32768
# 19     Name аватарка Type jpg sys 32768
Удаленные обьекты:
.0
..0
____________________
/Users/mesteriis/Downloads/uTorrent   sys 16384    <----- это для примера
Добавлено через 54 секунды
PS Там идет ругонь на имена переменных, я об этом знаю, поправлю потом. Так что в это носом чур не тыкать меня)
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.10.2015, 13:25
Ответы с готовыми решениями:

Компилятор не знает dirent.h
Как это исправить?

Метода chdir нет в dirent.h
Добрый день! Вопрос в следующем обновил я значит систему и xcode, открыл свой старый проект, где...

Работа с файлами в цикле.
Вообщем у меня стоит задача считать из текстового файла цифры, фаил состоит из ста строк в каждой...

Работа с указателями в цикле
Всем привет! Имеется цикл, который осуществляет операции с объектом некоторого класса: ...

8
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
22.10.2015, 13:40 2
Mesteriis, скорее всего функция stat фейлится. Возвращает ошибку (которую ты успешно не проверяешь). Поэтому заполненный единожды буфер
Цитата Сообщение от Mesteriis Посмотреть сообщение
C++
1
struct stat buf;
более не меняется.

Добавлено через 3 минуты
Mesteriis, я даже знаю почему она фейлится. Потому что
Цитата Сообщение от Mesteriis Посмотреть сообщение
C++
1
ent->d_name
не содержит в себе полный путь (или путь относительно текущего каталога программы), который нужен stat. Там содержится только имя файла в заданном каталоге.
0
599 / 237 / 69
Регистрация: 08.08.2015
Сообщений: 1,637
22.10.2015, 13:53  [ТС] 3
DrOffset, Ну подожди (ent->d_name) возвращяет полное имя (то есть name.ext) , естественно относительно заданного каталога (открытый DIR *dir = opendir(Target) соответсвенно для нее этого должно хватать вполне, или ей все таки надо передавать полный путь? я чой то запутался в конец(
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
22.10.2015, 14:01 4
Цитата Сообщение от Mesteriis Посмотреть сообщение
Ну подожди (ent->d_name) возвращяет полное имя (то есть name.ext) , естественно относительно заданного каталога
Давай на пальцах:
1) Программа сидит в каталоге /prog
2) Каталог, который сканируется - такой /prog/mydir
3) Имя файла в /prog/mydir возвращается, например, test.txt
4) Пихаем test.txt в stat, что получаем? Правильно, поиск в каталоге /prog. А там такого файла нет.

Мораль: нельзя забивать на обработку ошибок. Даже в тестовых примерах.
0
599 / 237 / 69
Регистрация: 08.08.2015
Сообщений: 1,637
22.10.2015, 14:10  [ТС] 5
DrOffset, Вот теперь понял, мерси, тоесть что бы все это работало, мне глобально надо менять рабочие каталоги? ну или передавать stat полные пути
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
22.10.2015, 14:14 6
Цитата Сообщение от Mesteriis Посмотреть сообщение
мне глобально надо менять рабочие каталоги?
Не надо.
Цитата Сообщение от Mesteriis Посмотреть сообщение
ну или передавать stat полные пути
Да, либо использовать пути относительно текущего каталога программы (он не обязательно всегда будет совпадать с каталогом, где программа находится физически).
0
599 / 237 / 69
Регистрация: 08.08.2015
Сообщений: 1,637
22.10.2015, 14:18  [ТС] 7
Цитата Сообщение от DrOffset Посмотреть сообщение
Не надо
А в чем опасность? разве не проще перенести рабочий каталог нежели чем сначала просчитывать (/Users/mesteriis/Downloads + namefile) полный путь к каждому файлу а потом передавать эту махину с каждым проходом в stat?
PS Это пока пишу он простенький и не особо много файлов, планируется в конечном счете работа с директориями где их (файлов) 10к
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
22.10.2015, 14:38 8
Лучший ответ Сообщение было отмечено Mesteriis как решение

Решение

Цитата Сообщение от Mesteriis Посмотреть сообщение
А в чем опасность?
В общем случае в том, что это глобальный ресурс, который надо защищать при использовании многопоточности. Ну и забыть вернуть как было можно, поломав другие части программы, которые на это завязались.
Тут проще всего вообще от функции stat уйти.
Вот примерно что-то такое (в windows не будет работать):
C++
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
struct EntryInfo
{
    enum Type
    {
        DIR, FILE
    };
 
    std::string name;
    Type type;
};
 
void GetEntries(const char * target, std::vector<EntryInfo> & names)
{
    if(DIR * dir = ::opendir(target))
    {
        while(struct dirent * ent = ::readdir(dir))
        {
            char const * name = ent->d_name;
            switch(ent->d_type)
            {
            case DT_DIR:
                if(std::strcmp(name, ".") && std::strcmp(name, ".."))
                {
                    EntryInfo inf = { name, EntryInfo::DIR };
                    names.push_back(inf);
                }
                break;
            case DT_REG:
                {
                    EntryInfo inf = { name, EntryInfo::FILE };
                    names.push_back(inf);
                }
            }
        }
        ::closedir(dir);
    }
}
1
599 / 237 / 69
Регистрация: 08.08.2015
Сообщений: 1,637
22.10.2015, 15:43  [ТС] 9
DrOffset, Мерси, в винде и не работаю уже лет так 5) спс за пример, буду думать дальше
0
22.10.2015, 15:43
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.10.2015, 15:43
Помогаю со студенческими работами здесь

работа с циклом и условием в цикле
Мне надо что бы после одного прохода цикла i=k-1 а после следующего прохода i=k+1 вобщем что б...

Работа с динамической памятью в цикле
Всем привет. Есть переменная data, созданная динамически На каждой итерации цикла в нее...

Работа с оператором switch в цикле
сhar ch; cin.get(ch); switch(ch) { case 'a': cout &lt;&lt; &quot;one &quot; &lt;&lt; endl; break; case 'b': cout...

Некорректная работа ф-ции getch() в цикле
while (iKey != 27) { iKey = getch(); cout &lt;&lt; &quot;qwer&quot;; } Не могу понять почему после...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru