Переписать входной файл в выходной в обратном порядке
Здравствуй народ знающий, народ всемогущий.
Решил реализовать такую вот простенькую задачу:
написать консольное приложение, которое получает на вход бинарный файл произвольного размера и в качестве результата создает новый файл, в котором содержимое входного файла записано в обратном порядке (побайтно). Имена входного и выходного файлов должны передаваться через параметры командной строки:
[[
program.exe input.dat output.dat
]]
Например, если на входе файл input.dat в котором записаны байты {0×0A, 0×00, 0×20, 0xFF}, то на выходе должен быть файл output.dat в котором записаны байты {0xFF, 0×20, 0×00, 0×0A}.
Подойдет ли решение для портфолио, и что можно было бы в нем изменить?
main.cpp
#include <iostream> #include <string> #include "OFile.h" #include "IFile.h" using namespace std; int main(int argc, char * argv[]) { switch (argc) { case 3: { OFile OutFile(argv[1]); IFile InFile(argv[2]); OutFile.Read(); int size = OutFile.getsize(); char **buffer = new char *[size]; for (int i = 0; i < size; i++) { buffer[i] = new char[2]; } for (int i = 0; i < size; i++) { buffer[i] = OutFile.getbuf(i); } InFile.Write(buffer, size); } cout << "THE END!" << endl; break; case 2: cout << "Missing 1 argument" << endl; break; case 1: cout << "Not arguments" << endl; break; default: cout << "Many arguments" << endl; break; } return 0; }
XFile.h
#pragma once #include <iostream> #include <string> #include <fstream> using namespace std; class XFile { public: ~XFile(); XFile(); protected: string FileName; /*Установка имени файла, и проверка на существование расширения файла .dat в названии*/ int CheckFile(char * name); /*закрытие файла процедуру необходимо перегрузить в производном классе*/ virtual void CloseFile(); /*открытие файла процедуру необходимо перегрузить в производном классе*/ virtual int OpenFile(); private: /*Проверка расширения файла, если не .dat, программа показывает соответствующее предупреждение и прекращает выполнение*/ int CheckFileExtansion(); void SetFileName(char * name); };
XFile.cpp
#include "XFile.h" XFile::XFile() { } XFile::~XFile() { } void XFile::SetFileName(char * name) { this->FileName = string(name); } int XFile::CheckFileExtansion() { string sep = "."; string name = FileName; string ext; size_t pos = 0; while ((pos = name.find(sep)) != string::npos) { ext = name.substr(0, pos); name.erase(0, pos + sep.length()); } if (name == "dat") { cout << FileName << ": file extention is correct" << endl; return 1; } else { cout << FileName << ": Invalid file extention" << endl; exit(10); } } int XFile::CheckFile(char * name) { SetFileName(name); CheckFileExtansion(); return 0; } void XFile::CloseFile() { cout << FileName<< ": Invalid close file" << endl; } int XFile::OpenFile() { cout << FileName << ": Invalid open file" << endl; return 0; }
OFile.h
#pragma once #include "XFile.h" class OFile : public XFile { public: /*Чтение всего содержимого файла*/ void Read(); /*Получение размера файла в байтах (символах)*/ int getsize(); /*Получение i-ого символа содержимого файла, не будет работать до вызова процедуры Read()*/ char* getbuf(int i); /*Файл открывается только для чтения, Название файла должно быть с расширением .dat, файл должен существовать в папке проекта*/ OFile(char * name); /*Закрытие файла и очистка буфера*/ ~OFile(); private: char** buffer; ifstream file; int sizefile; void CloseFile(); /*Открытие файла только для чтения*/ int OpenFile(); /*Вычисление размера файла в байтах (символах)*/ void setsize(); /*Получение кода символа в ASCII в 16-ричной системе счисления, результат выводится в виде символьной строки из 2-х символов типа "00"*/ char* convertChartoHex(char* c, int i); };
OFile.cpp
#include "OFile.h" void OFile::Read() { file.seekg(0, ios_base::beg); buffer = new char * [sizefile]; for (int i = 0; i < sizefile; i++) { buffer[i] = new char[2]; } for (int i = 0; i < sizefile; i++) { char *c = new char[2]; file.seekg(i, ios_base::beg); file.read(c, 1); c = convertChartoHex(c, i); buffer[i][0] = c[0]; buffer[i][1] = c[1]; } cout << FileName << ": Data is read" << endl; } OFile::OFile(char * name) { CheckFile(name); OpenFile(); setsize(); } OFile::~OFile() { CloseFile(); for (int i = 0; i < sizefile; i++) { delete[]buffer[i]; } delete[]buffer; } void OFile::CloseFile() { file.close(); cout << FileName << ": file is closed" << endl; } int OFile::OpenFile() { file.open(FileName, ios::binary | ios::in); if (!file) { cout << FileName<< ": Open file - Failed" << endl; exit(20); } else { cout << FileName << ": file is opened" << endl; } return 0; } void OFile::setsize() { file.seekg(0, ios_base::end); sizefile = file.tellg(); file.seekg(0, ios_base::beg); if (sizefile == -1){ cout << FileName<< ": Invalid size of file" << endl; exit(50); } } int OFile::getsize() { return sizefile; } char * OFile::getbuf(int i) { return buffer[i]; } char* OFile::convertChartoHex(char * c, int i) { int a = c[0]; int k = 0; char m[2] = {0,0}; int l = 0; while (l != 2) { k = a % 16; a = a / 16; switch (k) { case 0: m[l] = '0'; break; case 1: m[l] = '1'; break; case 2: m[l] = '2'; break; case 3: m[l] = '3'; break; case 4: m[l] = '4'; break; case 5: m[l] = '5'; break; case 6: m[l] = '6'; break; case 7: m[l] = '7'; break; case 8: m[l] = '8'; break; case 9: m[l] = '9'; break; case 10: m[l] = 'a'; break; case 11: m[l] = 'b'; break; case 12: m[l] = 'c'; break; case 13: m[l] = 'd'; break; case 14: m[l] = 'e'; break; case 15: m[l] = 'f'; break; } l++; } char n = m[0]; m[0] = m[1]; m[1] = n; return m; }
IFile.h
#pragma once #include "XFile.h" class IFile : public XFile { public: /*Запись содержимого buffer в файл, size указывает на размер buffer*/ void Write(char** buffer, int size); /*Файл открывается только для записи, Название файла должно быть с расширением .dat, если файла нет, он создастся, если файл существует, он перезапишется*/ IFile(char * name); /*Закрытие файла*/ ~IFile(); private: ofstream file; void CloseFile(); int OpenFile(); /*Вычисление символа из 16-ичной системы счисления согласно таблице ASCII, на вход подается строка из 2-х символов типа "00", должны присутствовать только цифры и буквы a,b,c,d,e,f результат выводится в виде 1-го символа*/ char convertHextoChar(char* c); };
IFile.cpp
#include "IFile.h" void IFile::Write(char** buffer, int size) { char *c = new char [size]; for (int i = size-1; i >= 0; i--) { c[size -1 - i] = convertHextoChar(buffer[i]); } file.write(c, size); cout << FileName << ": Data was written" << endl; } IFile::IFile(char * name) { CheckFile(name); OpenFile(); } IFile::~IFile() { CloseFile(); } void IFile::CloseFile() { file.close(); cout << FileName << ": file is closed" << endl; } int IFile::OpenFile() { file.open(FileName, ios::binary | ios::out); if (!file) { cout << FileName << ": Open file - Failed" << endl; exit(20); } else { cout << FileName << ": file is opened" << endl; } return 0; } char IFile::convertHextoChar(char * c) { int number[2]; switch (c[0]) { case '0': number[0] = 0; break; case '1': number[0] = 1; break; case '2': number[0] = 2; break; case '3': number[0] = 3; break; case '4': number[0] = 4; break; case '5': number[0] = 5; break; case '6': number[0] = 6; break; case '7': number[0] = 7; break; case '8': number[0] = 8; break; case '9': number[0] = 9; break; case 'a': number[0] = 10; break; case 'b': number[0] = 11; break; case 'c': number[0] = 12; break; case 'd': number[0] = 13; break; case 'e': number[0] = 14; break; case 'f': number[0] = 15; break; } switch (c[1]) { case '0': number[1] = 0; break; case '1': number[1] = 1; break; case '2': number[1] = 2; break; case '3': number[1] = 3; break; case '4': number[1] = 4; break; case '5': number[1] = 5; break; case '6': number[1] = 6; break; case '7': number[1] = 7; break; case '8': number[1] = 8; break; case '9': number[1] = 9; break; case 'a': number[1] = 10; break; case 'b': number[1] = 11; break; case 'c': number[1] = 12; break; case 'd': number[1] = 13; break; case 'e': number[1] = 14; break; case 'f': number[1] = 15; break; } int res = number[0] * 16 + number[1]; char sim = (char)res; return sim; }
Найкращі коментарі пропустити