Программа 2.3. cat: вывод нескольких файлов на стандартное устройство вывода
/* Глава 2. cat. */
/* cat [параметры] [файлы] Допускается только параметр –s, предназначенный для подавления вывода сообщений об ошибках в случае, если один из указанных файлов не существует. */
#include "EvryThng.h"
#define BUF_SIZE 0x200
static VOID CatFile(HANDLE, HANDLE);
int _tmain(int argc, LPTSTR argv[]) {
HANDLE hInFile, hStdIn = GetStdHandle(STD_INPUT_HANDLE);
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
BOOL DashS;
int iArg, iFirstFile;
/* Переменная DashS будет установлена только в случае задания параметра "-s" в командной строке. */
/* iFirstFile — индекс первого входного файла в списке argv[]. */
iFirstFile = Options(argc, argv, _T("s"), &DashS, NULL);
if (iFirstFile == argc) { /*Отсутствие входных файлов в списке аргументов.*/
/* Использовать стандартное устройство ввода. */
CatFile(hStdIn, hStdOut);
return 0;
}
/* Обработать каждый входной файл. */
for (iArg = iFirstFile; iArg < argc; iArg++) {
hInFile = CreateFile(argv [iArg], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hInFile == INVALID_HANDLE_VALUE && !DashS) ReportError (_T("Cat: ошибка при открытии файла"), 1, TRUE);
CatFile (hInFile, hStdOut);
CloseHandle (hInFile);
}
return 0;
}
/* Функция, выполняющая всю работу:
/* читает входные данные и копирует их на стандартное устройства вывода. */
static VOID CatFile(HANDLE hInFile, HANDLE hOutFile) {
DWORD nIn, nOut;
BYTE Buffer [BUF_SIZE];
while (ReadFile(hInFile, Buffer, BUF_SIZE, &nIn, NULL) && (nIn != 0) && WriteFile(hOutFile, Buffer, nIn, &nOut, NULL));
return;
}
Пример: преобразование символов из ASCII в Unicode
Программа 2.4 достраивает программу 1.3, в которой использовалась вспомогательная функция CopyFile. С копированием файлов вы уже знакомы, поэтому в данном примере эта операция дополняется преобразованием файла к кодировке Unicode в предположении, что первоначальной кодировкой символов является ASCII, хотя проверка этого предположения не производится. В программе предусмотрены некоторые возможности вывода сообщений об ошибках и параметр, позволяющий подавить замену существующего файла; завершающий вызов функции CopyFile заменен в программе вызовом новой функции, которая Выполняет преобразование символьных строк файла из кодировки ASCII в кодировку Unicode.
В данной программе основное внимание уделяется обеспечению возможности успешного завершения преобразования. Фактическое выполнение преобразования сосредоточено в единственной функции, вызываемой в самом конце программы. Этот фрагмент, как и аналогичный ему фрагмент предыдущей программы, послужит нам шаблоном и будет вновь использоваться в последующих программах без повторения его исходного кода.
Обратите внимание на вызов функции _taccess, проверяющей существование файла. Эта функция является обобщенной версией функции access, которая имеется в библиотеке UNIX, но не входит в состав стандартной библиотеки С. Ее определение содержится в файле . Если говорить точнее, функция _taccess осуществляет проверку прав доступа к файлу в соответствии с режимом, установленным значением второго параметра. Значение 0 задает проверку существования файла, 2 — проверку наличия разрешения на запись в файл, 4 — проверку наличия разрешения на чтение из файла, 6 — проверку наличия разрешения как на чтение из файла, так и на запись в файл (эти значения не связаны напрямую с такими параметрами доступа, используемыми в Windows, как GENERIC_READ). Альтернативой проверке существования файла могло бы быть открытие дескриптора при помощи функции CreateFile и его последующее закрытие после проверки действительности дескриптора.
Программа 2.4. atou: преобразование файла с выводом сообщений об ошибках
/* Глава 2. atou – копирование файлов с преобразованием из ASCII в Unicode. */
#include "EvryThng.h"
BOOL Asc2Un(LPCTSTR, LPCTSTR, BOOL);
int _tmain(int argc, LPTSTR argv[]) {
DWORD LocFileIn, LocFileOut;
BOOL DashI = FALSE;
TCHAR YNResp[3] = _T("y");
/* Получить параметры командной строки и индекс входного файла. */
LocFileIn = Options(argc, argv, _T("i"), &DashI, NULL);
LocFileOut = LocFileIn + 1;
if (DashI) { /* Существует ли выходной файл? */
/* Обобщенная версия функции access, осуществляющая проверку существования файла. */
if (_taccess(argv[LocFileOut], 0) == 0) {
_tprintf(_T("Перезаписать существующий файл? [y/n]"));
_tscanf(_T ("%s"), &YNResp);
if (lstrcmp(CharLower(YNResp), YES) != 0) ReportError(_T("Отказ от перезаписи"), 4, FALSE);
}
}
Читать дальше