Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.50/22: Рейтинг темы: голосов - 22, средняя оценка - 4.50
0 / 0 / 0
Регистрация: 22.04.2012
Сообщений: 36
1

Работа с фс

08.08.2012, 18:04. Показов 4104. Ответов 22
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет, мне необходимо посчитать количество файлов в директории и в зависимости от их количества разделить их на 4 или 8 папок. Я слышала есть библиотеки fstream и boost, но как правильно это сделать я так и не поняла.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.08.2012, 18:04
Ответы с готовыми решениями:

Нужна летиратура, в которой бы описывались работа с событиями, работа с элементами управления
Помогите пожалуйста найти летиратуру, в которой бы описывались работа с событиями,работа со всеми...

Работа - проведение обучающих семинаров по C#. Работа по выходным дням ( сб-вс - 32 часа). От 30 000р.
Обязанности - проведение обучающих семинаров по C# Базовый (начальный уровень). Опыт...

Количество подведенного и отведенного тепла, работа сжатия, работа расширения
Определить количество подведенного и отведенного тепла, работу сжатия, работу расширения, полезную...

Работа с Меню. Сохранение, печать, создать новый. Работа с рисованием
В общем сабж. Делается программа, которая должная Сохранять, печатать и очищать поле (создать...

22
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
08.08.2012, 18:07 2
А не проще ли использовать WinApi-функции? Сначала FindFirstFile, а затем FindNextFile. А папки это : CreateDirectory?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "stdafx.h"
#include "windows.h"
#include "iostream.h"
 
void main()
{
    WIN32_FIND_DATA FindFileData;
    HANDLE hf;
    hf=FindFirstFile("c:\\*", &FindFileData);
    if (hf!=INVALID_HANDLE_VALUE)
    {
        do
        {
            cout << FindFileData.cFileName << endl;
        }
        while (FindNextFile(hf,&FindFileData)!=0);
        FindClose(hf);
    }
}
0
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
08.08.2012, 18:21 3
Цитата Сообщение от nexen Посмотреть сообщение
А не проще ли использовать WinApi-функции?
Есть и другие системы, помимо windows

Mari-mari,
http://stackoverflow.com/quest... filesystem
1
0 / 0 / 0
Регистрация: 22.04.2012
Сообщений: 36
08.08.2012, 18:52  [ТС] 4
Цитата Сообщение от soon Посмотреть сообщение
Есть и другие системы, помимо windows

Mari-mari,
http://stackoverflow.com/quest... filesystem
Спасибо, посчитать количество файлов у меня получилось, а как быть с тем чтобы разделить эти файлы на 4 папки?
0
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
08.08.2012, 18:58 5
Mari-mari, что значит разделить? Переместить? По какому критерию?
0
0 / 0 / 0
Регистрация: 22.04.2012
Сообщений: 36
08.08.2012, 19:08  [ТС] 6
Цитата Сообщение от soon Посмотреть сообщение
Mari-mari, что значит разделить? Переместить? По какому критерию?
Ну скажем в папке лежит 107 файлов, я это определила, далее мне нужно разложить(скопировать) эти файлы пропорционально в 4 или 8 папок. Я так полагаю нужно 107 поделить на 4 и на 8, получится приблизительное количество файлов в одной папке. К примеру будет 27, 27, 27, 26 файлов в папках соответственно, но как это написать я не знаю. Да, критерия как бы нет, проще говоря из одной папки с большим количеством файлов нужно сделать 4 или 8 маленьких.
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
08.08.2012, 21:52 7
буз удаления оригиналов, если надо то допишем)
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
#include <string>
#include <iostream>
#include <exception>
#include <boost/filesystem.hpp>
 
namespace fs = boost::filesystem;
 
inline void make_new_path_from_current(fs::path& p, const std::string& str)
{
    p = fs::current_path() / str;
}
 
namespace cs {
    enum { FILES_IN_FOLDER = 27 };
}
 
int main()
{
    std::size_t current = 0;
    fs::path current_path;
 
    try 
    {
        for (auto i = fs::directory_iterator(fs::current_path()), end = fs::directory_iterator();
             i != end;
             ++i, ++current)
        {
            if (current % cs::FILES_IN_FOLDER == 0)
                make_new_path_from_current(current_path, std::to_string(current));
 
            if (fs::is_regular_file(i->path()))
            {
                if (fs::exists(current_path) == false)
                    fs::create_directory(current_path);
 
                fs::copy(i->path(), current_path / i->path().filename());
            }
        }
 
        std::cout << "Done!!!" << std::endl;
    }
    catch (std::exception const& ex)
    {
        std::cerr << "Exception: " << ex.what() << std::endl;
    }
}
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.08.2012, 22:10 8
Цитата Сообщение от nexen Посмотреть сообщение
А не проще ли использовать WinApi-функции? Сначала FindFirstFile, а затем FindNextFile. А папки это : CreateDirectory?
Цитата Сообщение от soon Посмотреть сообщение
Есть и другие системы, помимо windows
Тем более на мой взгляд boost куда удобнее.
0
0 / 0 / 0
Регистрация: 22.04.2012
Сообщений: 36
08.08.2012, 22:12  [ТС] 9
Цитата Сообщение от Jupiter Посмотреть сообщение
буз удаления оригиналов, если надо то допишем)
[/CPP]
При компиляции выдает такие ошибки
C++
1
2
3
4
5
6
7
8
9
10
11
12
Mari@desktop:~/test/forum$ g++ war.cpp -o war -lboost_filesystem -lboost_system
war.cpp: В функции «int main()»:
war.cpp:25:19: ошибка: «o» не является именем типа
war.cpp:26:14: ошибка: expected «;» before «i»
war.cpp:26:14: ошибка: нет декларации «i» в этой области видимости
war.cpp:26:19: ошибка: нет декларации «end» в этой области видимости
war.cpp:30:58: ошибка: «to_string» не является элементом «std»
war.cpp:37:17: ошибка: «copy» не является элементом «fs»
war.cpp:37:17: замечание: suggested alternatives:
/usr/include/c++/4.6/bits/stl_deque.h:369:5: замечание:   «std::copy»
/usr/include/boost/filesystem/v3/operations.hpp:289:8: замечание:   «boost::filesystem3::copy»
/usr/include/boost/filesystem/v3/operations.hpp:145:10: замечание:   «boost::filesystem3::detail::copy»
И если можно, то добавьте пожалуйста пару комментариев. Т.к. мне еще нужно указать местоположение папки со всеми файлами, а так же указать названия этих 4 или 8 папок в которые будет происходить копирование.. Ну я это сама попробую сделать.
0
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
08.08.2012, 22:18 10
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
#include <iostream>
#include <string>
#include <cerrno>
#include <array>
 
#include <boost/filesystem.hpp>
 
class directory_range
{
    using bfs_dir_iter = boost::filesystem::directory_iterator;
    bfs_dir_iter _itr;
 
public:
    directory_range(bfs_dir_iter&& itr): _itr(itr)
    {
 
    }
 
    bfs_dir_iter begin()
    {
        return _itr;
    }
 
    bfs_dir_iter end()
    {
        return bfs_dir_iter();
    }
};
 
int main()
{
    namespace bfs = boost::filesystem;
 
    bfs::path p("/home/soon/Src/C++/main/test");
    if(!bfs::is_directory(p))
    {
        std::cerr << "[ ERROR ] ";
        std::cerr << p << " isn't directory. Stopping...." << std::endl;
        return ENOENT;
    }
 
    std::array<std::string, 4> dirs{ {"first", "second", "third", "fourth"} };
 
    for(const auto& dir: dirs)
        try
        {
            bfs::create_directory(p / dir);
        }
        catch(const bfs::filesystem_error& e)
        {
                std::cerr   << "[ ERROR ] ";
                std::cerr   << (p / dir).filename() 
                            << " is already exists and not directory. "
                            << "Stopping..." << std::endl;
                return ENOENT;
        }
 
    auto dirs_iter = dirs.begin();
    for(const auto& file: directory_range(bfs::directory_iterator(p)))
    {
        if(!bfs::is_regular_file(file))
        {
            std::cerr   << "[WARNING] ";
            std::cerr   << file.path().filename() << " isn't regular file. "
                        << "Go to the hell, I will not copy it." << std::endl;
        }
        else
        {
            if(bfs::exists(p / *dirs_iter / file.path().filename()))
            {
                std::cerr   << "[WARNING] ";
                std::cerr   << file.path().filename()
                            << " is already exists in " << *dirs_iter
                            << ". Skipping..." << std::endl;
                continue;
            }
            
            bfs::copy(file, p / *dirs_iter++ / file.path().filename());
            if(dirs_iter == dirs.cend())
                dirs_iter = dirs.begin();
        }
    }
 
    return 0;
}

Не по теме:

Как можно использовать directory_iterator в range-based-for без самописной оболочки?

1
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
08.08.2012, 22:36 11
soon, Как вариант дописать перегрузки функций std::begin/std::end.
0
0 / 0 / 0
Регистрация: 22.04.2012
Сообщений: 36
08.08.2012, 22:44  [ТС] 12
Soon, ваш код по идее то, что мне нужно, но компилирую и выдает такое, может я компилирую не правильно?
Bash
1
g++ war.cpp -o war -lboost_filesystem -lboost_system
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
In file included from /usr/include/c++/4.6/array:35:0,
                 from war.cpp:4:
/usr/include/c++/4.6/bits/c++0x_warning.h:32:2: ошибка: #error This file requires compiler and library support for the upcoming ISO C++ standard, C++0x. This support is currently experimental, and must be enabled with the -std=c++0x or -std=gnu++0x compiler options.
war.cpp:10:11: ошибка: expected nested-name-specifier before «bfs_dir_iter»
war.cpp:10:11: ошибка: using-декларация для не-элемента внутри класса
war.cpp:10:24: ошибка: expected «;» before «=» token
war.cpp:10:24: ошибка: expected unqualified-id before «=» token
war.cpp:11:5: ошибка: «bfs_dir_iter» не является именем типа
war.cpp:14:27: ошибка: «bfs_dir_iter» не является именем типа
war.cpp:14:41: ошибка: ISO C++ запрещает декларации «itr» без типа [-fpermissive]
war.cpp:19:5: ошибка: «bfs_dir_iter» не является именем типа
war.cpp:24:5: ошибка: «bfs_dir_iter» не является именем типа
war.cpp: In constructor «directory_range::directory_range(const int&)»:
war.cpp:14:47: ошибка: в классе «directory_range» не имеет поля с именем «_itr»
war.cpp: В функции «int main()»:
war.cpp:42:5: ошибка: «array» не является элементом «std»
war.cpp:42:27: ошибка: expected primary-expression before «,» token
war.cpp:42:32: ошибка: нет декларации «dirs» в этой области видимости
war.cpp:42:36: ошибка: expected «;» before «{» token
war.cpp:85:1: ошибка: expected «}» at end of input
0
2554 / 1319 / 178
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
08.08.2012, 22:45 13
ForEveR, Можно, но я имел в виду что-то из буста. К примеру, шаблонный класс, в котором также есть аналогичные функции begin и end. Или конкретно из filesystem что-нибудь.

Добавлено через 41 секунду
Mari-mari, Как минимум -std=gnu++11(c++11 или c++0x)
0
0 / 0 / 0
Регистрация: 22.04.2012
Сообщений: 36
08.08.2012, 22:52  [ТС] 14
Цитата Сообщение от soon Посмотреть сообщение
Mari-mari, Как минимум -std=gnu++11(c++11 или c++0x)
Сработало только с++0x и то опять ошибки сыпятся...
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
27
g++ war.cpp -o war -lboost_filesystem -lboost_system -std=gnu++0x
war.cpp:10:11: ошибка: expected nested-name-specifier before «bfs_dir_iter»
war.cpp:10:11: ошибка: using-декларация для не-элемента внутри класса
war.cpp:10:24: ошибка: expected «;» before «=» token
war.cpp:10:24: ошибка: expected unqualified-id before «=» token
war.cpp:11:5: ошибка: «bfs_dir_iter» не является именем типа
war.cpp:14:27: ошибка: «bfs_dir_iter» не является именем типа
war.cpp:14:41: ошибка: ISO C++ запрещает декларации «itr» без типа [-fpermissive]
war.cpp:19:5: ошибка: «bfs_dir_iter» не является именем типа
war.cpp:24:5: ошибка: «bfs_dir_iter» не является именем типа
war.cpp: In constructor «directory_range::directory_range(const int&)»:
war.cpp:14:47: ошибка: в классе «directory_range» не имеет поля с именем «_itr»
war.cpp: В функции «int main()»:
war.cpp:59:69: ошибка: нет подходящей функции для вызова «directory_range::directory_range(boost::filesystem3::directory_iterator)»
war.cpp:59:69: замечание: candidates are:
war.cpp:14:5: замечание: directory_range::directory_range(const int&)
war.cpp:14:5: замечание:   no known conversion for argument 1 from «boost::filesystem3::directory_iterator» to «const int&»
war.cpp:8:7: замечание: constexpr directory_range::directory_range(const directory_range&)
war.cpp:8:7: замечание:   no known conversion for argument 1 from «boost::filesystem3::directory_iterator» to «const directory_range&»
war.cpp:8:7: замечание: constexpr directory_range::directory_range(directory_range&&)
war.cpp:8:7: замечание:   no known conversion for argument 1 from «boost::filesystem3::directory_iterator» to «directory_range&&»
war.cpp:59:69: ошибка: unable to deduce «const auto&» from «<expression error>»
war.cpp:78:13: ошибка: «copy» не является элементом «bfs»
war.cpp:78:13: замечание: suggested alternatives:
/usr/include/c++/4.6/bits/stl_deque.h:369:5: замечание:   «std::copy»
/usr/include/boost/filesystem/v3/operations.hpp:289:8: замечание:   «boost::filesystem3::copy»
/usr/include/boost/filesystem/v3/operations.hpp:145:10: замечание:   «boost::filesystem3::detail::copy»
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
08.08.2012, 22:56 15
Цитата Сообщение от Mari-mari Посмотреть сообщение
war.cpp:78:13: ошибка: «copy» не является элементом «bfs»
какая версия буста? чтоб исправить эту ошибку попробуй
это
Цитата Сообщение от soon Посмотреть сообщение
C++
1
namespace bfs = boost::filesystem;
заменить на
C++
1
namespace bfs = boost::filesystem3;
0
0 / 0 / 0
Регистрация: 22.04.2012
Сообщений: 36
08.08.2012, 23:01  [ТС] 16
Цитата Сообщение от Jupiter Посмотреть сообщение
какая версия буста? чтоб исправить эту ошибку
это

замени на
C++
1
namespace bfs = boost::filesystem3;
Не помогло, версия буста 1.46, ставила из синаптика. Ну в смысле я весь пакет ставила, сейчас посмотрела, точно 1.46.
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
08.08.2012, 23:41 17
Mari-mari, вот немного переделанный код soon
на gcc 4.6.3 vs boost 1.46 скомпилировалось
Bash
1
g++ main.cpp -std=c++0x -lboost_filesystem -lboost_system
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
#include <iostream>
#include <iterator>
#include <string>
#include <cerrno>
 
#include <boost/filesystem.hpp>
 
class directory_range
{
    typedef boost::filesystem3::directory_iterator bfs_dir_iter;
    bfs_dir_iter _itr;
 
public:
    directory_range(bfs_dir_iter&& itr): _itr(itr)
    {
    }
 
    bfs_dir_iter begin()
    {
        return _itr;
    }
 
    bfs_dir_iter end()
    {
        return bfs_dir_iter();
    }
};
 
int main()
{
    namespace bfs = boost::filesystem3;
 
    bfs::path p("/home/maxwe11/test/t");
    if(!bfs::is_directory(p))
    {
        std::cerr << "[ ERROR ] ";
        std::cerr << p << " isn't directory. Stopping...." << std::endl;
        return ENOENT;
    }
 
    const char* dirs[] = {"first", "second", "third", "fourth"};
 
    for(const auto& dir: dirs)
        try
        {
            bfs::create_directory(p / dir);
        }
        catch(const bfs::filesystem_error& e)
        {
                std::cerr   << "[ ERROR ] ";
                std::cerr   << (p / dir).filename()
                            << " is already exists and not directory. "
                            << "Stopping..." << std::endl;
                return ENOENT;
        }
 
    auto dirs_iter = std::begin(dirs);
    for(const auto& file: directory_range(bfs::directory_iterator(p)))
    {
        if(!bfs::is_regular_file(file))
        {
            std::cerr   << "[WARNING] ";
            std::cerr   << file.path().filename() << " isn't regular file. "
                        << "Go to the hell, I will not copy it." << std::endl;
        }
        else
        {
            if(bfs::exists(p / *dirs_iter / file.path().filename()))
            {
                std::cerr   << "[WARNING] ";
                std::cerr   << file.path().filename()
                            << " is already exists in " << *dirs_iter
                            << ". Skipping..." << std::endl;
                continue;
            }
 
            bfs::copy(file, p / *dirs_iter++ / file.path().filename());
            if(dirs_iter == std::end(dirs))
                dirs_iter = std::begin(dirs);
        }
    }
 
    return 0;
}
1
0 / 0 / 0
Регистрация: 22.04.2012
Сообщений: 36
08.08.2012, 23:59  [ТС] 18
Soon, Jupiter, ребят спасибо вам огромное, очень приочень выручили.
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
09.08.2012, 00:16 19
soon, boost::iterator_range же.

C++
1
2
3
for (const auto& f : boost::make_iterator_range(bfs::directory_iterator(p), bfs::directory_iterator()))
{
}
Пример.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <sstream>
#include <iostream>
#include <iterator>
 
#include <boost/range/iterator_range.hpp>
 
int main()
{
   std::stringstream ss;
   ss << "hello";
   for (const auto& c : boost::make_iterator_range
   (std::istream_iterator<char>(ss), std::istream_iterator<char>()))
   {
      std::cout << c << std::endl;
   }
}
http://liveworkspace.org/code/... 061f66fada
2
13 / 13 / 0
Регистрация: 11.10.2011
Сообщений: 116
09.08.2012, 00:33 20
Хм, почитал - интересно. У буста, конечно, возможности только воображением ограничены Есть вариант сборки прог без флага -std=c++0x?
0
09.08.2012, 00:33
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.08.2012, 00:33
Помогаю со студенческими работами здесь

Работа формы в фоне, вне фокуса (работа с раскладкой клавиатуры)
Как заставить это работать в фоне? Даный код работает пока форма в фокусе, как только ее...

Работа с файловой системой (системное название некоторых папок и работа со скрытыми документами)
Всем привет, подскажите каким образом можно из VBA сохранить документ txt в папке &quot;Общие...

Нужна книга, где рассматриваются работа с прерываниями, указатели, работа с памятью, ассемблерные вставки
Привет всем! Подскажите, пожалуйста, хорошую книгу по C (именно C, не C++). Интересует работа с...

Работа с файлом (корректный код, некорректная работа программы)
Для записи и чтения файла использую разные функции. По одиночке они работают нормально. Вставляю...


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

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