Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
russian_pepper
43 / 0 / 0
Регистрация: 14.06.2014
Сообщений: 130
#1

Получить список файлов в каталоге

30.04.2015, 01:23. Просмотров 2734. Ответов 18
Метки нет (Все метки)

Здравствуйте!
Мне нужно получить список файлов в каталоге, чтобы потом как-то работать с этими файлами, для начала, отсортировать их по дате, которая есть в названии файла в формате *_ЧЧ.ММ.ГГГГ_*. Во всех видеоуроках и книгах, которые мне попадают, хорошо описан только ввод-вывод из файла. Подскажите, где лучше всего описана работа с файлами в каталоге. Нашёл готовый пример, вроде бы можно воспользоваться, но хотелось бы хорошо понимать, как тут всё работает...
Искал HANDLE и WIN32_FIND_DATAA у Б. Пахомова, Т, А. Павловской, Шилдта, Прата, нашёл только у А. Хортона Visual C++ 2010. Полный курс, сказано (handle) это дескриптор, подобие указателя, но что к чему и зачем пока не понимаю. Помогите кто-нибудь объясните, как пример ниже работает, или что прочитать нужно, возможно в моём случае, только для считывания имён файлов из каталога, всё ещё проще чем в примере ниже решается?
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
#include <iostream>
#include <Windows.h>
using namespace std;
 
int main()
{
    setlocale(LC_ALL, "Russian");
 
    WIN32_FIND_DATAA findData;
    HANDLE hf;
 
    hf = FindFirstFileA("D:\\MyDocs\\*", &findData);
 
    if (hf == INVALID_HANDLE_VALUE)
    {
        cout << "Cannot find file" << endl;
        return -1;
    }
 
    do
    {
        if(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            cout << "[DIR] ";
            
        cout << findData.cFileName << endl;
    }
    while (FindNextFileA(hf, &findData)); 
 
    FindClose(hf);
 
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.04.2015, 01:23
Ответы с готовыми решениями:

Список файлов в каталоге
Добрый день. Хочу получить список файлов из папки, решение ниже работает, но в...

Вывести список файлов в каталоге
Напишите программу, которая составляет список файлов, расположенных в каталоге,...

Список файлов в указанном каталоге
Использую функцию FindFirstFile: hf = FindFirstFile(L&quot;c:\\folder\\*&quot;,...

Вывод на экран список файлов и название программ С++ , находящимся в указанном при запуске программы каталоге
Добрый день! Помогите пожалуйста: Написать программу, которая выведет на...

Получить список файлов в папке С++17
Здравствуйте! Вопрос наверное невероятно глупый, но я не смог нагуглить и...

18
nmcf
6260 / 5572 / 2532
Регистрация: 14.04.2014
Сообщений: 23,464
30.04.2015, 07:54 #2
Проще не получится, и так всё просто. В 12-й строке поиск первого, затем в цикле просмотр остальных. Только здесь каталоги отбираются, тебе надо атрибуты файлов задать вместо FILE_ATTRIBUTE_DIRECTORY.
0
russian_pepper
43 / 0 / 0
Регистрация: 14.06.2014
Сообщений: 130
30.04.2015, 13:47  [ТС] #3
nmcf, А как это правильно сделать? Где лучше об этом прочитать?
0
Ilot
Эксперт С++
1828 / 1186 / 342
Регистрация: 16.05.2013
Сообщений: 3,127
Записей в блоге: 5
Завершенные тесты: 1
30.04.2015, 14:44 #4
Лучший ответ Сообщение было отмечено russian_pepper как решение

Решение

russian_pepper, не там ищите.
Побегайло Системное программирование в Windows
0
russian_pepper
43 / 0 / 0
Регистрация: 14.06.2014
Сообщений: 130
05.05.2015, 15:26  [ТС] #5
Ilot, Здравствуйте!
Книгу хорошую подсказали, спасибо, но в процессе изучения ещё вопрос возник...
Вариант ниже в переменной k считает директории правильно, вопросов нет, но мне нужны файлы.
Когда ставлю FILE_ATTRIBUTE_NORMAL, ничего не считает. Если ставлю FILE_ATTRIBUTE_ARCHIVE, то находит все мои файлы которые мне нужны, но когда смотрю в свойствах файлов, галочки в атрибутах "Только чтение" нет, а в дополнительных атрибутах галка в поле "Файл готов для архивирования" и "Разрешить индексировать содержимое...
В чём причина?
Файл готов для архивирования - это и есть ARCHIVE?
А какие тогда фалы должны находиться если file_attribute_normal записать?
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
#include <iostream>
#include <Windows.h>
using namespace std;
 
int main()
{
    setlocale(LC_ALL, "Russian");
 
    WIN32_FIND_DATAA findData;
    HANDLE hf;
    
    hf = FindFirstFileA("D:\\temp\\*", &findData);
 
    if (hf == INVALID_HANDLE_VALUE)
    {
        cout << "Cannot find file" << endl;
        return -1;
    }
int k = 0;
    do
    {
        if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            cout << k << ' ' << "[DIR] ";
            k++;
        }
 
        cout << findData.cFileName << endl;
 
    } while (FindNextFileA(hf, &findData));
cout << k << endl;
 
    FindClose(hf);
    system("pause");
}
0
nmcf
6260 / 5572 / 2532
Регистрация: 14.04.2014
Сообщений: 23,464
05.05.2015, 15:55 #6
NORMAL - это когда совсем без атрибутов. Сними все флажки в проводнике у файла и попробуй поиск.
1
russian_pepper
43 / 0 / 0
Регистрация: 14.06.2014
Сообщений: 130
05.05.2015, 16:21  [ТС] #7
nmcf, Здравствуйте!
Тогда ещё вопрос: У меня совсем другая программа пишет информацию в разные файлы на Qpile. Никаких установок в языке по атрибутам файлов нет. Просто пишет по умолчанию как-то и всё данные в том формате в котором я указал. Чем определяются атрибуты файлов в таком случае? Это Windows определяет или что-то ещё? Как эти атрибуты вообще появляются если я никогда нигде явно не указываю их? У меня около 8000 этих файлов и мне надо правильно их обработать, раньше такого никогда не делал...
0
nmcf
6260 / 5572 / 2532
Регистрация: 14.04.2014
Сообщений: 23,464
05.05.2015, 16:46 #8
Ну архивный атрибут автоматически устанавливается по-видимому, атрибут сжатия может наследоваться от папки или вручную устанавливаться и т. д. Можешь просто взять все атрибуты, связанные с файлами на диске, и так отбирать.
1
russian_pepper
43 / 0 / 0
Регистрация: 14.06.2014
Сообщений: 130
08.05.2015, 00:38  [ТС] #9
Здравствуйте!
Подскажите, как в программе выше правильно сделать, чтобы передавать разные маски в FindFirstFileA.
Просто объявить, например:
C++
1
string s = "D:\\temp\\*_??.??.????.csv";
и вписать:
C++
1
hf = FindFirstFileA(s, &findData);
не получается.
У меня всего пока две разных маски и конечно могу два раза повторить нужный фрагмент программы, но хотелось бы понять, как сделать красиво и правильно...
0
Ilot
Эксперт С++
1828 / 1186 / 342
Регистрация: 16.05.2013
Сообщений: 3,127
Записей в блоге: 5
Завершенные тесты: 1
08.05.2015, 07:30 #10
Лучший ответ Сообщение было отмечено russian_pepper как решение

Решение

C++
1
hf = FindFirstFileA(s.c_str(), &findData);
0
nmcf
6260 / 5572 / 2532
Регистрация: 14.04.2014
Сообщений: 23,464
08.05.2015, 10:02 #11
Вообще-то FindFirstFileA() - это из музея. Пора уже FindFirstFileW() использовать.
1
russian_pepper
43 / 0 / 0
Регистрация: 14.06.2014
Сообщений: 130
08.05.2015, 15:17  [ТС] #12
Ilot, Здравствуйте!
Подскажите пожалуйста, как правильно это сделать в моём случае? FindFirstFileW() в книге которую мне рекомендовали выше нет, посмотрел Go To Definition, там всё так же как и у FindFirstFileA, это всё, на что ума пока хватило...
Можете подсказать, что к чему, где это лучше посмотреть? На разных форумах где упоминается FindFirstFileW() и FindFirstFileA(), понял, только что связано что-то с кодировкой, но примеров понятных для себя не нашёл.
0
nmcf
6260 / 5572 / 2532
Регистрация: 14.04.2014
Сообщений: 23,464
08.05.2015, 15:24 #13
Программа будет по сути такая же, только с поддержкой Unicode. Вместо char используй wchar_t, вместо string - wstring и т. п.
0
russian_pepper
43 / 0 / 0
Регистрация: 14.06.2014
Сообщений: 130
08.05.2015, 16:11  [ТС] #14
string - wstring понятно, а где тут char ?

Добавлено через 45 минут
Заменил:
WIN32_FIND_DATAA findData; на WIN32_FIND_DATAW findData;
string... на wstring s = "D:\\temp\\*_??.??.????.csv";
hf = FindFirstFileA(s.c_str(), &findData); на hf = FindFirstFileW(s.c_str(), &findData);
while (FindNextFileA(hf, &findData)); на while (FindNextFileW(hf, &findData));

подчёркивает "D:\\temp\\*_??.??.????.csv";
Error 1 error C2440: 'initializing' : cannot convert from 'const char [25]' to 'std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>'

В чём ошибка?
0
nmcf
6260 / 5572 / 2532
Регистрация: 14.04.2014
Сообщений: 23,464
08.05.2015, 18:49 #15
Про L у строковых констант не забывай и про W у функций и структур при необходимости.
C++
1
2
3
4
WIN32_FIND_DATAW findData;
wstring s = L"D:\\temp\\*_??.??.????.csv";
hf = FindFirstFileW(s.c_str(), &findData);
while (FindNextFileW(hf, &findData));
0
russian_pepper
43 / 0 / 0
Регистрация: 14.06.2014
Сообщений: 130
08.05.2015, 19:43  [ТС] #16
Так в результате выдаётся адрес 004FF7FC, а раньше название файла выводилось, что-то ещё не так....
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
#include <iostream>
#include <Windows.h>
using namespace std;
 
int main()
{
    setlocale(LC_ALL, "Russian");
    WIN32_FIND_DATAW findData;
    HANDLE hf;
    wstring s = L"D:\\temp\\*_??.??.????.csv";
    hf = FindFirstFileW(s.c_str(), &findData);
 
    if (hf == INVALID_HANDLE_VALUE)
    {
        cout << "Cannot find file" << endl;
        return -1;
    }
    int k = 0;
    do
    {
        if (findData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)
        {
            k++;
            cout << findData.cFileName << endl;
        }
    } while (FindNextFileW(hf, &findData));
    cout << k << endl;
 
    FindClose(hf);
    system("pause");
}
0
nmcf
6260 / 5572 / 2532
Регистрация: 14.04.2014
Сообщений: 23,464
08.05.2015, 20:02 #17
wcout вместо cout.
1
russian_pepper
43 / 0 / 0
Регистрация: 14.06.2014
Сообщений: 130
08.05.2015, 20:46  [ТС] #18
nmcf, Спасибо, всё работает!
Не сочтите за труд, объясните, такие вещи нужно узнавать и запоминать или как-то легко можно догадаться?
Мне когда написали что лучше FindFirstFileW() вместо FindFirstFileA()использовать, то часть я догадался и исправил правильно по подсказкам в VS, но вот L пропустил в wstring s = L"D:\\temp\\*_??.??.????.csv"; и wcout вместо cout, тоже не знал...
Это можно было как-то догадаться или найти VisualStudio или только перебирать в сети кучу примеров и смотреть похожие на свою задачу?
0
nmcf
6260 / 5572 / 2532
Регистрация: 14.04.2014
Сообщений: 23,464
08.05.2015, 23:20 #19
Догадаться о чём? Широкие строки и символы идут с префиксом L - это стандарт. Широкие потоки wcout и wcin тоже есть в С++, если читать не древние книжки.
Есть ещё макрос _T() вроде бы для VS, который зависит от того, включен или нет Unicode в свойствах проекта.
Функции тоже будут подставляться соответствующие если явно не указано.
1
08.05.2015, 23:20
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.05.2015, 23:20

Получить список файлов в директории
Всем доброго времени суток. Я хочу получить список файлов в директории любым...

Получить список файлов и папок
Имеется строка в которой содержится адрес некоторой папки. Как можно получить...

Получить список файлов и папок в директории
Вот такой вопрос возник, допустим я хочу написать что то типа файлового...


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru