Переписать входной файл в выходной в обратном порядке
13.12.2018, 09:09. Показов 1729. Ответов 0
Здравствуй народ знающий, народ всемогущий.
Есть одно тестовое задание:
написать консольное приложение, которое получает на вход бинарный файл произвольного размера и в качестве результата создает новый файл, в котором содержимое входного файла записано в обратном порядке (побайтно). Имена входного и выходного файлов должны передаваться через параметры командной строки:
[[
program.exe input.dat output.dat
]]
Например, если на входе файл input.dat в котором записаны байты {0x0A, 0x00, 0x20, 0xFF}, то на выходе должен быть файл output.dat в котором записаны байты {0xFF, 0x20, 0x00, 0x0A}.
И есть одно решение этого тестового задания, написал сам, рабочий, (тапками бросаться рекомендую, но только с обоснованиями, что не так, чего не хватает, и возможным примером исправления, может какой-то литературой).
В общем, жду критики
main.cpp
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 <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
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
| #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
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
| #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
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
| #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
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
| #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
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
| #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
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 "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;
} |
|
0
|