Инструменты пользователя

Инструменты сайта


fajl

Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

fajl [2018/11/16 06:16] (текущий)
Строка 1: Строка 1:
 +====== Примеры работы с файлами на С, С++======
 +
 +{{htmlmetatags>​
 +metatag-description=(Функции для работы с содержимым файла библиотеки языка C.)
 +}}
 +
 +Определение:​ **Файл** - это именованный блок информации,​ расположенный на носителе информации.
 +
 +Любой файл обладает следующим рядом особенностей: ​
 +  * Файл не может располагаться на диске непрерывно,​ однако пользователю файл предоставляется цельным блоком последовательной байтовой информации.
 +  * Название файла не может содержать символы:​ < > : " / \ |.
 +  * Большинство файлов обладает расширением - сочетанием символов,​ с помощью которых операционная система определяет тип файла. Расширение - необязательная часть.
 +  * У каждого файла есть, так называемые атрибуты,​ которые,​ например,​ определяют уровни доступа к нему. Используя атрибуты,​ операционная система узнает,​ как нужно и, главное,​ можно, работать с данным файлом.
 +Термины:​
 +  * **Дескриптор файла** - уникальный номер, который операционная система присваивает любому открытому файлу, что бы отличать его от других. Когда файл закрывается,​ система "​отбирает"​ у него дескриптор. Именно это уникальное число мы будем использовать для работы с конкретным файлом в наших программах.
 +  * **Файловый указатель** - специальная переменная,​ которая автоматически присваивается открытому файлу и хранит текущую позицию в файле. Она перемещается по файлу в момент процессов записи и чтения. Для большего понимания,​ вы можете представить данную переменную в виде курсора в любом текстовом редакторе.
 +Существует несколько разновидностей файлов. В Windows таких разновидностей две: текстовый файл и бинарный (двоичный) файл.
 +<note important>​Файл можно открыть в текстовом или в двоичном режиме. Внимание,​ не следует это отождествлять с текстовым и двоичным форматами!!! Разница между режимами открытия состоит в том, что при открытии файла в двоичном режиме информация будет в том же виде, в котором она хранится на диске или в памяти. А, вот, при текстовом режиме символ окончания строки (\n) будет заменяться на двойное сочетание (\r\n). Это как обычно связано с "​нестыковкой"​ систем MS DOS и Windows.</​note>​
 +====== Функции для работы с содержимым файла библиотеки языка C ======
 +===== Функции библиотеки stdio.h =====
 +==== fopen ====
 +<​file>​
 +FILE *fopen(const char *filename, const char *mode)
 +</​file>​
 +
 +Функция открывает файл.
 +
 +filename - путь к файлу
 +
 +mode - тип доступа
 +
 +<​file>​
 +r - чтение,​ если файла нет, то данная функция генерирует ошибку (возвращает 0) 
 +w - запись,​ если файла нет, то файл создаётся,​ если есть исходное содержимое удаляется ​
 +a - добавление в конец, если файла нет, то он создаётся ​
 +r+ чтение и запись (файл должен существовать) ​
 +w+ - чтение и запись (принцип работы как у w) 
 +a+ - добавление и чтение (принцип работы как у a)
 +</​file> ​
 +<​note>​Все вышеописанные режимы предназначены для текстового открытия файла. Для двоичного открытия перед режимом достаточно добавить букву b. Например,​ br.</​note>​
 +Если функция отработала успешно,​ из неё возвращается указатель на открытый файл, в противном случае - нуль. ​
 +
 +<​note>​Указатель на открытый файл принято хранить в типе данных FILE*.</​note>​
 +
 +==== fclose ====
 +int fclose( FILE *stream )
 +
 +Функция закрывает файл.
 +
 +stream - указатель на закрываемый файл.
 +
 +Если всё проходит успешно,​ то данная функция возвращает 0, или EOF в случае ошибки. ​
 +<​note>​EOF (End Of File) - обозначение конца файла.</​note> ​
 +
 +
 +char *fgets( char *string, int n, FILE *stream )
 +
 + 
 +
 +Считывает строку начиная с текущей позиции.
 +
 +Считывание останавливается:​
 +
 +...если был найден символ перехода на новую строчку ( он помещается в строку ) 
 +...если достигнут конец файла ​
 +...если считано n-1 символов. ​
 +string - cтрока,​ в которую попадают считанные данные
 +
 +n - количество элементов в string
 +
 +stream - указатель на открытый файл
 +
 +Если всё прошло успешно функция возвращает считанную строку,​ если произошла ошибка или достигнут конец файла возвращается 0. 
 +
 +
 +int fputs( const char *string, FILE *stream )
 +
 + 
 +
 +Записывает строку в файл, начиная с текущей позиции.
 +
 +string - строка для записи
 +
 +stream - указатель на открытый файл, куда производиться запись
 +
 +Если функция отрабатывает успешно из неё возвращается неотрицательное значение. При ошибке возвращается EOF.
 +
 +
 +--------------------------------------------------------------------------------
 +size_t fread( void *buffer, size_t size, size_t count, FILE *stream )
 +
 + 
 +
 +Функция считывает данные из файла в буфер.
 +
 +buffer - адрес массива,​ куда запишутся данные
 +
 +size - размер элемента массива в байтах
 +
 +count - максимальное количество элементов для считывания
 +
 +stream - указатель на открытый файл.
 +
 +Функция возвращает количество считанных байт.
 +
 +Примечание:​ Тип данных size_t определен в библиотеке stdio.h следующим образом:​ typedef unsigned int size_t;. Другими словами,​ это обычный беззнаковый int. 
 +
 +--------------------------------------------------------------------------------
 +size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream )
 +
 + 
 +
 +Функция записывает массив данных в файл.
 +
 +buffer - адрес массива,​ где содержатся данные
 +
 +size - размер элемента массива в байтах
 +
 +count - максимальное количество элементов для записи в файл
 +
 +stream - указатель на открытый файл.
 +
 +Функция возвращает количество записанных байт.
 +
 +
 +--------------------------------------------------------------------------------
 +int feof( FILE *stream )
 +
 + 
 +
 +Функция проверяет достигнут ли конец файла.
 +
 +stream - указатель на открытый файл
 +
 +Функция возвращает ненулевое значение,​ если достигнут конец файла, нуль возвращается в противном случае.
 +
 +
 +--------------------------------------------------------------------------------
 +int _fileno( FILE *stream )
 +
 + 
 +
 +Данная функция возвращает дескриптор файла.
 +
 +stream - указатель на открытый файл.
 +
 +
 +--------------------------------------------------------------------------------
 +int fseek ( FILE *stream, int offset [, int whence] )
 +
 + 
 +
 +Устанавливает смещение в файле
 +
 +stream - указатель на открытый файл
 +
 +offset - смещение,​ измеряемое в байтах от начала файла
 +
 +whence - точка, от которой производится смещение
 +
 +SEEK_SET (0) - начало файла ​
 +SEEK_CUR (1) - позиция текущего указателя файла ​
 +SEEK_END (2) - конец файла (EOF) 
 +Функция возвращает значение 0, если указатель файла успешно перемещен,​ и ненулевое значение в случае неудачного завершения. ​
 +
 +
 +--------------------------------------------------------------------------------
 +
 +===== Функции библиотеки io.h =====
 +==== _access ====
 +int _access( const char *path, int mode ) Функция определяет разрешения файла или директории.
 +  * path - путь к файлу или директории
 +  * mode - флаги для проверки<​file>​
 +00 - проверка на существование ​
 +02 - проверка на разрешение на запись ​
 +04 - проверка на разрешение на чтение ​
 +06 - проверка на чтение и запись
 +</​file> ​
 +Если разрешение есть, функция возвращает ноль, в случае отсутствия -1.
 +<​note>​Директории можно проверять только на существование.</​note>​
 +<​file>​
 +//​проверить существует объект или нет? Если нет выйти из программы.
 + if (_access(str,​ 00)!=0){
 + cout<<"​Object \""<<​str<<"​\"​ does not exist."<<"​\n";​
 + exit;
 + }
 +</​file>​
 +==== _filelength ====
 +long _filelength( int handle )
 +
 +Возвращает размер файла в байтах.
 +
 +handle - дескриптор файла.
 +
 +В случае ошибки функция возвращает -1.
 +
 +int _locking( int handle, int mode, long nbytes )
 +
 +
 +Блокирует или разблокирует байты файла начиная с текущей позиции в файле. ​
 +
 +handle - дескриптор файла
 +
 +mode - тип блокировки
 +
 +_LK_LOCK - блокирует байты, если заблокировать байты не получается попытка повторяется через 1 секунду.Если после 10 попыток байты не заблокируются функция генерирует ошибку и возвращает -1 
 +_LK_NBLCK - блокирует байты, если заблокировать байты не получается функция генерирует ошибку и возвращает -1 
 +_LK_NBRLCK - то же самое, что и _LK_NBLCK ​
 +_LK_RLCK - то же самое, что и _LK_LOCK ​
 +_LK_UNLCK - разблокировка байт, которые были до этого заблокированы ​
 +nbytes - количество байт для блокировки
 +
 +Функция locking возвращает -1, если происходит ошибка и 0 в случае успеха.
 +
 +<​note>​Для работы этой функции кроме io.h, нужно подключить sys/​locking.h</​note>​
 +====== Функции для работы с файлами и директориям ======
 +stdio.h - переименование и удаление файлов.
 +===== rename =====
 +rename (char * oldname, char * newname)
 +
 +Переименовывает файл.
 +
 +oldname - путь и текущее имя файла newname - путь и новое имя файла
 +
 +Функция возвращает 0, если имя файла было успешно изменено,​ и ненулевое значение,​ если замена не произошла.
 +
 +<note important>​Если указать не только новое имя, но и новый путь - файл будет не только переименован,​ но и перенесён.</​note>​
 +===== remove =====
 +int remove(const char * filename) Удаляет файл.
 +
 +filename - путь и имя файла
 +
 +Функция возвращает 0, если имя файл был успешно удален,​ и ненулевое значение,​ если удаление не произошло.
 +<note important>​Помните!!! В момент удаления файл должен быть закрыт. Кроме того, не забывайте,​ что удаление необратимо.</​note>​
 +===== _chmod =====
 +Установка прав на файл.
 +<​file>​
 +#include <​sys/​stat.h>​
 +#include <​io.h>​
 +
 +_chmod( "​test.txt",​ _S_IREAD ); // установить атрибут только для чтения на файл test.txt
 +</​file>​
 +===== _findfirst _findnext =====
 +  * **_findfirst**(char * path, _finddata_t * fileinfo)
 +io.h - поиск файлов.
 +Находит файлы по указанному пути, соответствующие маске.
 +
 +<​file>​
 +Маска - строка,​ критерий поиска,​ содержащая символы * (любая последовательность любых символов) и ? (любой один символ) ​
 +path - строка,​ в которой содержится комбинация пути и маски.
 +</​file>​
 +**fileinfo** - указатель на объект структуры , в который запишется информация о найденном файле. Структура _finddata_t содержит следующие поля:
 +<​file>​
 +unsigned attrib - содержит информацию об атрибутах файла. ​
 +_A_NORMAL - Обычный файл без запретов на чтение или запись. ​
 +_A_RDONLY - Файл только для чтения. ​
 +_A_HIDDEN - Скрытый файл. ​
 +_A_SYSTEM - Системный файл. ​
 +_A_SUBDIR - Директория. ​
 +_A_ARCH - Архивный файл. ​
 +time_t time_create - время/​дата создания файла (равно -1 для FAT систем). ​
 +time_t time_access - время/​дата последнего открытия файла (равно -1 для FAT систем). ​
 +time_t time_write - время/​дата последнего редактирования файла ​
 +_fsize_t size - размер файла ​
 +char name[260] - имя файла
 +</​file> ​
 +Если всё пройдет успешно,​ информация о первом найденном файле запишется в объект структуры _finddata_t. При этом в оперативной памяти сформируется "​список",​ обладающий внутренним указателем,​ который изначально будет установлен на первом найденном файле. В этом случае функция вернет уникальный номер, связанный с полученной группой файлов. Если поиск завершится неудачей,​ функция вернет -1. 
 +  * **_findnext**(long done, _finddata_t * fileinfo) Функция осуществляет переход на следующий найденный файл в группе.
 +done - уникальный номер группы файлов в памяти.
 +fileinfo - указатель на объект структуры,​ в который запишется информация о следующем найденном файле.
 +Если достигнут конец списка файлов,​ функция вернет -1.
 +  * **_findclose**(long done) Функция очищает память от группы найденных файлов. done - уникальный номер группы файлов в памяти.
 +===== Как удалить файл? =====
 +  * Если важна переносимость можно использовать класс boost/​filesystem/​operations.hpp ​
 +<​file>​
 +namespace boost
 +{
 + ​namespace filesystem
 + {
 +  bool remove( const path & ph );
 +  unsigned long remove_all( const path & ph );
 + }
 +}
 +</​file>​http://​www.boost.org
 +  * <​file>​
 +BOOL DeleteFile(LPCTSTR lpFileName);​
 +CFile::​Remove(LPCTSTR lpFileName);//​Просто вызывает DeleteFile()
 +</​file>​
 +  * Мне остается только назвать неназванный способ:​
 +
 +WINSHELLAPI int WINAPI SHFileOperation(LPSHFILEOPSTRUCT lpFileOp)
 + 
 +
 +
 +Для этого надо заполнить основные поля структуры SHFILEOPSTRUCT:​
 +<​file>​
 +
 +HWND hwnd; — родительское окно
 +
 +UINT wFunc; — в твоем случае FO_DELETE
 +
 +LPCSTR pFrom; — путь удаляемго файла (можно использовать маски!)
 +
 +FILEOP_FLAGS fFlags; — флаги; например OF_FILESONLY (мучить только файлы),​ OF_SILENT (не выводить индикатор) и др.
 +</​file>​
 +Там есть еще некоторые другие поля, разберешься. Подробнее читай Программист №1_2001 (http://​www.programme.ru)
 +
 +В чем преимущество этого способа:​
 +1. Индикатор удаления. Если файлов много юзер сможет наблюдать виндосное окошко
 +2. Можно использовать маски в именах файлов
 +  * <​file>​
 +int _unlink( const char *filename );
 +</​file>​
 +
 +===== Вывести атрибуты файла, директории =====
 +Программа выводит атрибуты файла или директории,​ переданные через командную строку.
 +<​file>​
 +#include <​cstdlib>​
 +#include <​cstring>​
 +#include <​iostream>​
 +#include <​io.h>​
 +#include <​ctime>​
 +
 +using namespace std;
 +
 +int main(int argc, char** argv) {
 + if(argc==1) exit(1);
 + struct _finddata_t fileinfo;
 + char str[200];
 + strcpy(str,​argv[1]);​
 + long done = _findfirst(str,​ &​fileinfo);​
 + char szBuffer[30];​
 +
 + //​Преобразование времени
 + ctime_s ( szBuffer, _countof (szBuffer),&​fileinfo.time_write);​
 +
 + printf ( " %-24s %.24s %9ld ", fileinfo.name,​ szBuffer, fileinfo.size);​
 + cout<<"​\n";​
 + printf( ( fileinfo.attrib & _A_SUBDIR ) ? "​d"​ : "​-"​ );
 + printf( ( fileinfo.attrib & _A_RDONLY ) ? "​r"​ : "​-"​ );
 + printf( ( fileinfo.attrib & _A_HIDDEN ) ? "​h"​ : "​-"​ );
 + printf( ( fileinfo.attrib & _A_SYSTEM ) ? "​s"​ : "​-"​ );
 + printf( ( fileinfo.attrib & _A_ARCH )   ? "​a"​ : "​-"​ );
 + printf( ( fileinfo.attrib & _A_NORMAL ) ? "​n"​ : "​-"​ );
 + cout<<"​\n";​
 +
 + _findclose(done);​
 +}
 +</​file>​
 +===== Пример программы на работу с файлами =====
 +<​file>​
 +// Здесь находятся функции переименования и удаления
 +#include <​stdio.h>​
 +// Здесь находятся функции для поиска файлов ​   ​
 +#include <​io.h> ​      
 +#include <​string.h>​
 +#include <​iostream>​
 +using namespace std;
 +// для функции AnsiToOem
 +#include <​windows.h>​
 +
 +// Переименовать существующий файл
 +void RenameFile();​
 +
 +// Удалить существующий файл
 +void RemoveFile(); ​  
 +
 +// Поиск файлов в каталоге
 +void Dir(); ​   ​
 +
 +void main()
 +{
 + // предлагаем выбрать пункт меню для выполнения
 + cout << "​Please,​ select preffer number...\n";​
 +
 + //​выбор пользователя
 + char ch; 
 + do{
 + // Переименовать
 + cout << "\n1 - Rename\n";​
 + // Удалить ​  
 + cout << "2 - Remove\n"; ​  
 + // Просмотреть некоторую папку(каталог)
 + cout << "3 - View some folder\n";​
 + // Выход
 + cout << "0 - Exit\n\n"; ​   ​
 + cin >> ch;
 +
 + // анализируем и вызываем ​
 + // соответствующую ​ функцию
 + switch(ch)
 + {
 + case '​1':​
 + RenameFile(); ​  
 + break;
 + case '​2':​
 + RemoveFile(); ​  
 + break;
 + case '​3':​
 + Dir();
 + break;
 + }
 + } while(ch != '​0'​); ​     // Выход из программы
 +}
 +
 +// Переименовать существующий файл
 +void RenameFile() ​      
 +{
 + char oldName[50],​ newName[50];​
 +
 + // В одной переменной запомним существующее имя (oldName), ​
 + cout << "Enter old name:";​
 + cin >> oldName;
 +
 + // А в другой новое имя(newName)
 + cout << "Enter new name:";​
 + cin >> newName;
 +
 + // Произведем переименование и проверку результата
 + if (rename(oldName,​ newName) != 0)
 + cout << "​Error!\n Couldn'​t rename file. Check old and new filename...\n\n";​
 + else 
 + cout << "​Ok...\n\n";​
 +}
 +
 +// Удалить существующий файл
 +void RemoveFile() ​          
 +{
 + char Name[50];
 + // Получаем имя и путь к удаляемому файлу
 + cout << "Enter name:";​
 + cin >> Name;
 +
 + //​Удаляем файл и проверяем результат
 + if (remove(Name) != 0)
 + cout << "​Error!\n Couldn'​t remove file. Check filename...\n";​
 + else 
 + cout << "​Ok...\n"​ ;
 +}
 +
 +// Поиск файлов в каталоге
 +void Dir()                        ​
 +{
 + // Запросим ПУТЬ (например,​ папка Temp на диске C, запишется ​
 + // таким вот образом:​ c:\temp\)
 + char path[70];
 + cout << "​\nEnter full path (for example, C:​\\):";​
 + cin >> path;
 +
 + // Запросим маску файлов ​
 + char mask[15];
 + cout << "​\nEnter mask (for example, *.* or *.txt):";​
 + cin >> mask;
 +
 + // Соединив две строки,​ мы получим результат
 + // т.е. что хочет найти пользователь и где
 + strcat(path,​ mask);
 +
 + // Объявление указателя fileinfo на структуру _finddata_t
 + // и создание динамического объекта структуры _finddata_t
 +    _finddata_t *fileinfo=new _finddata_t;​
 +
 + // Начинаем поиск
 + long done = _findfirst(path,​fileinfo);​
 +
 + // если done будет равняться -1, 
 + // то поиск вести бесмысленно
 + int MayWeWork = done;
 +
 + // Счетчик,​ содержит информацию о количестве найденых файлов.
 + int count = 0;   
 + while (MayWeWork!=-1)
 + {
 + count++;
 + // перекодировали имя найденного файла
 + // на случай,​ если оно кириллическое
 + AnsiToOem(fileinfo->​name,​fileinfo->​name);​
 + // Распечатали имя найденного файла
 + cout << fileinfo->​name << "​\n\n"; ​
 + // Пытаемся найти следующий файл из группы
 + MayWeWork = _findnext(done,​ fileinfo); ​       ​
 + }
 + // Вывод сообщения о количестве найденных файлов.
 + cout << "​\nInformation:​ was found " << count;
 + cout << " file(s) in folder..."​ << path << "​\n\n";​
 +
 + // Очистка памяти
 + _findclose(done);​
 + delete fileinfo;
 +}
 +</​file>​
 +====== Операции по работе с директориями ======
 +Библиотека direct.h
 +
 +  * int _mkdir( const char *dirname )
 +
 +Создает директорию по указанному пути.
 +
 +dirname - Путь и имя для создаваемой директории. В одно и то же время может быть создан только одна директория.
 +
 +  * int _rmdir( const char *dirname )
 +
 +Удаляет директорию по указанному пути.
 +
 +dirname - Путь и имя для удаляемой директории.
 +
 +Обе функции возвращают -1 в случае ошибки.
 +
 +<​note>​Для переименования директории можно использовать функцию rename из библиотеки stdio.h.</​note>​
 +<​file>​
 +Удалить и переименовать можно только пустую директорию!!!
 +</​file>​
 +
 +Пример на работу с директориями.
 +<​file>​
 +#include <​iostream>​
 +#include <​direct.h>​
 +#include <​stdio.h>​
 +
 +using namespace std;
 +
 +// Переименовать существующую директорию
 +void RenameDirectory();​
 +
 +// Удалить существующую директорию
 +void RemoveDirectory(); ​  
 +
 +// создать директорию
 +void CreateDirectory(); ​   ​
 +
 +void main()
 +{
 + // предлагаем выбрать пункт меню для выполнения
 + cout << "​Please,​ select preffer number...\n";​
 +
 + //​выбор пользователя
 + char ch; 
 + do{
 + // Переименовать
 + cout << "\n1 - Rename\n";​
 + // Удалить ​  
 + cout << "2 - Remove\n"; ​  
 + // Создать
 + cout << "3 - Create\n";​
 + // Выход
 + cout << "0 - Exit\n\n"; ​   ​
 + cin >> ch;
 +
 + // анализируем и вызываем ​
 + // соответствующую ​ функцию
 + switch(ch)
 + {
 + case '​1':​
 + RenameDirectory(); ​  
 + break;
 + case '​2':​
 + RemoveDirectory(); ​  
 + break;
 + case '​3':​
 + CreateDirectory();​
 + break;
 + }
 + } while(ch != '​0'​); ​     // Выход из программы
 +}
 +
 +// Переименовать существующую директорию
 +void RenameDirectory() ​      
 +{
 + char oldName[50],​ newName[50];​
 +
 + // В одной переменной запомним существующее имя (oldName), ​
 + cout << "Enter old name:";​
 + cin >> oldName;
 +
 + // А в другой новое имя(newName)
 + cout << "Enter new name:";​
 + cin >> newName;
 +
 + // Произведем переименование и проверку результата
 + if (rename(oldName,​ newName) != 0)
 + cout << "​Error!\n Couldn'​t rename directory.\n\n";​
 + else 
 + cout << "​Ok...\n\n";​
 +}
 +
 +// Удалить существующую директорию
 +void RemoveDirectory() ​          
 +{
 + char Name[50];
 + // Получаем имя и путь к удаляемой директории
 + cout << "Enter name:";​
 + cin >> Name;
 +
 + //​Удаляем директорию и проверяем результат
 + if (_rmdir(Name) == -1)
 + cout << "​Error!\n Couldn'​t remove directory.\n";​
 + else 
 + cout << "​Ok...\n"​ ;
 +}
 +// Создать директорию
 +void CreateDirectory() ​          
 +{
 + char Name[50];
 + // Получаем имя и путь к создаваемой директории
 + cout << "Enter name:";​
 + cin >> Name;
 +
 + //​Создаем директорию и проверяем результат
 + if (_mkdir(Name) == -1)
 + cout << "​Error!\n Couldn'​t create directory.\n";​
 + else 
 + cout << "​Ok...\n"​ ;
 +}
 +</​file>​
 +
 +====== Практический пример. Показ содержимого директории. ======
 +Пример программы осуществляющей показ содержимого директории. Программа при запуске показывает содержимое текущей директории,​ а затем дает пользователю возможность выбора. Ввести можно будет следующие команды: ​
 +
 +cd Путь - переход в другую директорию. ​
 +<​file>​
 +cd .. - показ содержимого родительского каталога и переход. ​
 +cd или cd . - показ содержимого текущего каталога. ​
 +exit - выход из программы. ​
 +root - переход в корневой каталог.
 +</​file> ​
 +<​note>​Все вышеперечисленные команды регистронезависимы.</​note> ​
 +<​file>​
 +#include <​iostream>​
 +#include <​windows.h>​
 +#include <​io.h>​
 +#include <​stdio.h>​
 +using namespace std;
 +
 +const int size=255;
 +
 +// Функция,​ которая убирает лишние слеши и пробелы справа ​
 +void RemoveRSpacesAndRSlashes(char *str){
 + int index=strlen(str)-1;​
 + while(str[index]=='​\\'​||str[index]=='​ '){
 + index--;
 + }
 + strncpy(str,​str,​index);​
 + str[index+1]='​\0';​
 +}
 +// Функция для показа текущей директории
 +void ShowCurrentDir(char path[],char temp[]){
 + CharToOem(path,​temp);​
 + printf("​%s>",​temp);​
 +}
 +// Функция перевода из кодировки
 +// Windows в кодировку DOS
 +// Для корректного отображения
 +// кирилицы
 +void RussianMessage(char path[]){
 + CharToOem(path,​path);​
 +}
 +
 +// Показ на экран содержимого папки
 +bool ShowDir(char path[]){
 + // Показ содержимого текущей директории
 + _finddata_t find;
 + char pathfind[MAX_PATH];​
 + strcpy(pathfind,​path);​
 + strcat(pathfind,"​\\*.*"​);​
 + char info[MAX_PATH];​
 +
 + // Начало Поиска
 + int result=_findfirst(pathfind,&​find);​
 + // Очистка экрана
 + system("​cls"​);​
 + int flag=result;​
 + if (flag==-1) {
 + strcpy(info,"​Такой Директории Нет"​);​
 + RussianMessage(info);​
 + printf("​%s\n",​info);​
 + return false;
 + }
 +
 + while(flag!=-1){
 +
 + if(strcmp(find.name,"​."​)&&​strcmp(find.name,"​.."​)){
 + // Проверяем Директория или Нет
 + find.attrib&​_A_SUBDIR?​strcpy(info,"​ Каталог "​):​strcpy(info,"​ Файл ");
 + RussianMessage(info);​
 + RussianMessage(find.name);​
 + printf("​%30s %10s\n",​find.name,​info);​
 + }
 + // Продолжаем Поиск
 + flag=_findnext(result,&​find);​
 + }
 +
 + ShowCurrentDir(path,​info);​
 + // Очищаем ресурсы,​ выделенные под поиск
 + _findclose(result);​
 + return true;
 +}
 +
 +void main(){
 + // В данной переменной будет храниться путь к Директории
 + char path[MAX_PATH];​
 + // В данной переменной будет команда,​ введенная пользователем
 + char action[size];​
 + // Временная переменная
 + char temp[MAX_PATH];​
 + // Получаем Путь к текущей Директории
 + GetCurrentDirectory(sizeof(path),​path);​
 +
 + bool flag=true;
 +
 + // Показ содержимого текущей директории
 + ShowDir(path);​
 + do{
 + // Ввод команды пользователя
 + cin.getline(action,​size);​
 + // Убираем пробелы и слэши справа
 + RemoveRSpacesAndRSlashes(action);​
 + // Переход в корневой каталог
 + if(!strcmpi(action,"​root"​)){
 + path[2]='​\0';​
 + ShowDir(path);​
 + }
 + // Проверка на желание пользователя выйти ​
 + else if(!strcmpi(action,"​exit"​)){
 + flag=false;​
 + }
 + // Проверка на команду cd
 + else if(!strnicmp(action,"​cd",​2)){
 + // Показ содержимого текущей директории
 + if((!strcmpi(action,"​cd"​))){
 + // Показ Директории
 + ShowDir(path);​
 + }
 + // Команда cd была дана с параметрами ​
 + else if(!strnicmp(action,"​cd ",3)){
 + // Находим индекс параметра ​
 + int index=strspn(action+2,"​ ");
 + if(index){
 + // Проверка на полный путь к Директории
 + if(strchr(action+index+2,':'​)){
 + // Попытка отобразить содержимое Директории
 + if(ShowDir(action+index+2)){
 + strcpy(path,​action+index+2);​
 + }
 + else{
 + // Произошла Ошибка
 + ShowCurrentDir(path,​temp);​
 + }
 + }
 + // Поднимаемся в родительский каталог
 + else if(!strcmp(action+index+2,"​.."​)){
 + char *result=strrchr(path,'​\\'​);​
 + if(result){
 + int delta=result-path;​
 + strncpy(temp,​path,​delta);​
 + temp[delta]='​\0';​
 + }
 + else{
 + strcpy(temp,​path);​
 + }
 +
 + if(ShowDir(temp)){
 + strcpy(path,​temp);​
 + }
 + else{
 + // Произошла Ошибка
 + ShowCurrentDir(path,​temp);​
 + }
 + }
 + // Показ Директории
 + else if(!strcmp(action+index+2,"​."​)){
 + ShowDir(path);​
 + }
 + else if(!strcmp(action+index+2,"/"​)){
 + ShowDir(path);​
 + }
 + else{
 + // Был Дан неполный путь ​
 + strcpy(temp,​path);​
 + strcat(temp,"​\\"​);​
 + strcat(temp,​action+index+2);​
 + // Попытка отобразить содержимое Директории
 + if(ShowDir(temp)){
 + strcpy(path,​temp);​
 + }
 + else{
 + // Произошла Ошибка
 + ShowCurrentDir(path,​temp);​
 + }
 + }
 + }
 + else{
 + // Показ Директории
 + ShowDir(path);​
 + }
 + }
 + else{
 + // Показ Директории
 + ShowDir(path);​
 + }
 + }
 + else{
 + // Показ Директории
 + ShowDir(path);​
 + }
 + }while(flag);​
 +
 +}
 +</​file>​
  
загрузка...
fajl.txt · Последние изменения: 2018/11/16 06:16 (внешнее изменение)