Final-2: Save Geometry Objects to Binary File (35%)
-
Inputs:
- Read geometry objects from a input file.
- Please use
int main(int argc, char *argv[])
to open the input file (Ref: One and the only: main function. - The file path of the input file is given as
argv[1]
.
- Please use
- Read the dimensions (
dim
) of the coordinate system. The dimension is anunsigned
between 2 and 10. - Read the type of geometry object in
char
format with the following types:l
for linet
for trianglep
for polygon
- Read the number of vertices in
unsigned
format for each type of geometry object as shown above.- line: 2
- triangle: 3
- polygon: \(n \in Z^+, n \ge 3\)
- Read the vertices with
dim
coordinates indouble
format.- line:
<double 1><double 2>...<double dim><double 1><double 2>...<double dim>
- triangle:
<double 1><double 2>...<double dim><double 1><double 2>...<double dim><double 1><double 2>...<double dim>
- polygon:
<double 1><double 2>...<double dim><double 1><double 2>...<double dim>...
- line:
- Read geometry objects from a input file.
-
Outputs:
- Write geometry objects to a output file.
- Please use
int main(int argc, char *argv[])
to open the input file (Ref: One and the only: main function. - The file path of the output file is given as
argv[2]
.
- Please use
- Write the dimensions of the coordinate system.
- Write all geometric objects in the input, with the following information:
- Write the type of the object, the number of vertices, and the vertices.
- The format shold follow the descriptions in Format.
- The order of the vertices and coordinates should be the same as the input.
- Each coordinate should be saved with
double
format.
- Write the type of the object, the number of vertices, and the vertices.
- Write the dimension and all geometric objects after the input is finished, and exit the program.
- Write geometry objects to a output file.
-
File name:
final-2_<student_id>.cpp
(e.g.final-2_106062802.cpp
) -
The program will not have any user prompts, only print the result.
-
The program does not need to handle invalid inputs.
-
The program should base on the
main
&print_output_file
function provided in the pseudo code. -
The program should be finished within 10 seconds. Any test cases will garuntee the program is finished within 10 seconds.
Format
Input/Output File
<dim><geometry type><n><double 1><double 2>...<double dim><double 1><double 2>...<double dim>...<EOF>
Example
Note: For any #
started lines are comments for human-readability. The .bin
files do not have comments.
dim = 2
Triangle
Input File: input_triangle_2d.bin
# 2
# t
# 3
# 1.000000000000000,2.000000000000000
# 3.000000000000000,4.000000000000000
# 5.000000000000000,0.000000000000000
# Hex dump
02 00 00 00 74 03 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08
40 00 00 00 00 00 00 10 40 00 00 00 00 00 00 14
40 00 00 00 00 00 00 00 00
Output File: output_triangle_2d.bin
02 00 00 00 74 03 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08
40 00 00 00 00 00 00 10 40 00 00 00 00 00 00 14
40 00 00 00 00 00 00 00 00
Terminal:
$ ./a.out input_triangle_2d.bin output_triangle_2d.bin
02 00 00 00 74 03 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08
40 00 00 00 00 00 00 10 40 00 00 00 00 00 00 14
40 00 00 00 00 00 00 00 00
$
Line
Input File: input_line_2d.bin
# 2
# l
# 2
# 1.000000000000000,2.000000000000000
# 3.000000000000000,4.000000000000000
# Hex dump
02 00 00 00 6c 02 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08
40 00 00 00 00 00 00 10 40
Output File: output_line_2d.bin
02 00 00 00 6c 02 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08
40 00 00 00 00 00 00 10 40
Terminal:
$ ./a.out input_line_2d.bin output_line_2d.bin
02 00 00 00 6c 02 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08
40 00 00 00 00 00 00 10 40
$
Polygon
Input File: input_polygon_2d.bin
# 2
# p
# 5
# 1.000000000000000,0.000000000000000
# 2.000000000000000,1.100000000000000
# -3.000000000000000,-2.200000000000000
# 4.300000000000000,2.100000000000000
# -1.200000000000000,3.400000000000000
# Hex dump
02 00 00 00 70 05 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40 9a 99 99 99 99 99 f1 3f 00 00 00 00 00 00 08
c0 9a 99 99 99 99 99 01 c0 33 33 33 33 33 33 11
40 cd cc cc cc cc cc 00 40 33 33 33 33 33 33 f3
bf 33 33 33 33 33 33 0b 40
Output File: output_polygon_2d.bin
02 00 00 00 70 05 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40 9a 99 99 99 99 99 f1 3f 00 00 00 00 00 00 08
c0 9a 99 99 99 99 99 01 c0 33 33 33 33 33 33 11
40 cd cc cc cc cc cc 00 40 33 33 33 33 33 33 f3
bf 33 33 33 33 33 33 0b 40
Terminal:
$ ./a.out input_polygon_2d.bin output_polygon_2d.bin
02 00 00 00 70 05 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40 9a 99 99 99 99 99 f1 3f 00 00 00 00 00 00 08
c0 9a 99 99 99 99 99 01 c0 33 33 33 33 33 33 11
40 cd cc cc cc cc cc 00 40 33 33 33 33 33 33 f3
bf 33 33 33 33 33 33 0b 40
$
Multiple Objects
Input File: input_multiple_objects_2d.bin
# 2
# t
# 3
# 1.000000000000000,2.000000000000000
# 3.000000000000000,4.000000000000000
# 5.000000000000000,0.000000000000000
# l
# 2
# 1.000000000000000,2.000000000000000
# 3.000000000000000,4.000000000000000
# p
# 5
# 1.000000000000000,0.000000000000000
# 2.000000000000000,1.100000000000000
# -3.000000000000000,-2.200000000000000
# 4.300000000000000,2.100000000000000
# -1.200000000000000,3.400000000000000
# Hex dump
02 00 00 00 74 03 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08
40 00 00 00 00 00 00 10 40 00 00 00 00 00 00 14
40 00 00 00 00 00 00 00 00 6c 02 00 00 00 00 00
00 00 00 00 f0 3f 00 00 00 00 00 00 00 40 00 00
00 00 00 00 08 40 00 00 00 00 00 00 10 40 70 05
00 00 00 00 00 00 00 00 00 f0 3f 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 40 9a 99 99 99 99
99 f1 3f 00 00 00 00 00 00 08 c0 9a 99 99 99 99
99 01 c0 33 33 33 33 33 33 11 40 cd cc cc cc cc
cc 00 40 33 33 33 33 33 33 f3 bf 33 33 33 33 33
33 0b 40
Output File: output_multiple_objects_2d.bin
02 00 00 00 74 03 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08
40 00 00 00 00 00 00 10 40 00 00 00 00 00 00 14
40 00 00 00 00 00 00 00 00 6c 02 00 00 00 00 00
00 00 00 00 f0 3f 00 00 00 00 00 00 00 40 00 00
00 00 00 00 08 40 00 00 00 00 00 00 10 40 70 05
00 00 00 00 00 00 00 00 00 f0 3f 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 40 9a 99 99 99 99
99 f1 3f 00 00 00 00 00 00 08 c0 9a 99 99 99 99
99 01 c0 33 33 33 33 33 33 11 40 cd cc cc cc cc
cc 00 40 33 33 33 33 33 33 f3 bf 33 33 33 33 33
33 0b 40
Terminal:
$ ./a.out input_multiple_2d.bin output_multiple_2d.bin
02 00 00 00 74 03 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08
40 00 00 00 00 00 00 10 40 00 00 00 00 00 00 14
40 00 00 00 00 00 00 00 00 6c 02 00 00 00 00 00
00 00 00 00 f0 3f 00 00 00 00 00 00 00 40 00 00
00 00 00 00 08 40 00 00 00 00 00 00 10 40 70 05
00 00 00 00 00 00 00 00 00 f0 3f 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 40 9a 99 99 99 99
99 f1 3f 00 00 00 00 00 00 08 c0 9a 99 99 99 99
99 01 c0 33 33 33 33 33 33 11 40 cd cc cc cc cc
cc 00 40 33 33 33 33 33 33 f3 bf 33 33 33 33 33
33 0b 40
$
dim = 3
Triangle
Input File: input_triangle_3d.bin
# 3
# t
# 3
# 1.000000000000000,2.000000000000000,3.000000000000000
# 3.000000000000000,4.000000000000000,5.000000000000000
# 5.000000000000000,0.000000000000000,1.000000000000000
# Hex dump
03 00 00 00 74 03 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08
40 00 00 00 00 00 00 08 40 00 00 00 00 00 00 10
40 00 00 00 00 00 00 14 40 00 00 00 00 00 00 14
40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0
3f
Output File: output_triangle_3d.bin
03 00 00 00 74 03 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08
40 00 00 00 00 00 00 08 40 00 00 00 00 00 00 10
40 00 00 00 00 00 00 14 40 00 00 00 00 00 00 14
40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0
3f
Terminal:
$ ./a.out input_triangle_3d.bin output_triangle_3d.bin
03 00 00 00 74 03 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08
40 00 00 00 00 00 00 08 40 00 00 00 00 00 00 10
40 00 00 00 00 00 00 14 40 00 00 00 00 00 00 14
40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0
3f
$
Line
Input File: input_line_3d.bin
# 3
# l
# 2
# 1.000000000000000,2.000000000000000,3.000000000000000
# 3.000000000000000,4.000000000000000,5.000000000000000
# Hex dump
03 00 00 00 6c 02 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08
40 00 00 00 00 00 00 08 40 00 00 00 00 00 00 10
40 00 00 00 00 00 00 14 40
Output File: output_line_3d.bin
03 00 00 00 6c 02 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08
40 00 00 00 00 00 00 08 40 00 00 00 00 00 00 10
40 00 00 00 00 00 00 14 40
Terminal:
$ ./a.out input_line_3d.bin output_line_3d.bin
03 00 00 00 6c 02 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08
40 00 00 00 00 00 00 08 40 00 00 00 00 00 00 10
40 00 00 00 00 00 00 14 40
$
Polygon
Input File: input_polygon_3d.bin
# 3
# p
# 5
# 1.000000000000000,0.000000000000000,-1.000000000000000
# 2.000000000000000,1.100000000000000,0.200000000000000
# -3.000000000000000,-2.200000000000000,-1.300000000000000
# 4.300000000000000,2.100000000000000,0.100000000000000
# -1.200000000000000,3.400000000000000,-5.600000000000000
# Hex dump
03 00 00 00 70 05 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0
bf 00 00 00 00 00 00 00 40 9a 99 99 99 99 99 f1
3f 9a 99 99 99 99 99 c9 3f 00 00 00 00 00 00 08
c0 9a 99 99 99 99 99 01 c0 cd cc cc cc cc cc f4
bf 33 33 33 33 33 33 11 40 cd cc cc cc cc cc 00
40 9a 99 99 99 99 99 b9 3f 33 33 33 33 33 33 f3
bf 33 33 33 33 33 33 0b 40 66 66 66 66 66 66 16
c0
Output File: output_polygon_3d.bin
03 00 00 00 70 05 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0
bf 00 00 00 00 00 00 00 40 9a 99 99 99 99 99 f1
3f 9a 99 99 99 99 99 c9 3f 00 00 00 00 00 00 08
c0 9a 99 99 99 99 99 01 c0 cd cc cc cc cc cc f4
bf 33 33 33 33 33 33 11 40 cd cc cc cc cc cc 00
40 9a 99 99 99 99 99 b9 3f 33 33 33 33 33 33 f3
bf 33 33 33 33 33 33 0b 40 66 66 66 66 66 66 16
c0
Terminal:
$ ./a.out input_polygon_3d.bin output_polygon_3d.bin
03 00 00 00 70 05 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0
bf 00 00 00 00 00 00 00 40 9a 99 99 99 99 99 f1
3f 9a 99 99 99 99 99 c9 3f 00 00 00 00 00 00 08
c0 9a 99 99 99 99 99 01 c0 cd cc cc cc cc cc f4
bf 33 33 33 33 33 33 11 40 cd cc cc cc cc cc 00
40 9a 99 99 99 99 99 b9 3f 33 33 33 33 33 33 f3
bf 33 33 33 33 33 33 0b 40 66 66 66 66 66 66 16
c0
$
Multiple Objects
Input File: input_multiple_objects_3d.bin
# 3
# t
# 3
# 1.000000000000000,2.000000000000000,3.000000000000000
# 3.000000000000000,4.000000000000000,5.000000000000000
# 5.000000000000000,0.000000000000000,1.000000000000000
# l
# 2
# 1.000000000000000,2.000000000000000,3.000000000000000
# 3.000000000000000,4.000000000000000,5.000000000000000
# p
# 5
# 1.000000000000000,0.000000000000000,-1.000000000000000
# 2.000000000000000,1.100000000000000,0.200000000000000
# -3.000000000000000,-2.200000000000000,-1.300000000000000
# 4.300000000000000,2.100000000000000,0.100000000000000
# -1.200000000000000,3.400000000000000,-5.600000000000000
# Hex dump
03 00 00 00 74 03 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08
40 00 00 00 00 00 00 08 40 00 00 00 00 00 00 10
40 00 00 00 00 00 00 14 40 00 00 00 00 00 00 14
40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0
3f 6c 02 00 00 00 00 00 00 00 00 00 f0 3f 00 00
00 00 00 00 00 40 00 00 00 00 00 00 08 40 00 00
00 00 00 00 08 40 00 00 00 00 00 00 10 40 00 00
00 00 00 00 14 40 70 05 00 00 00 00 00 00 00 00
00 f0 3f 00 00 00 00 00 00 00 00 00 00 00 00 00
00 f0 bf 00 00 00 00 00 00 00 40 9a 99 99 99 99
99 f1 3f 9a 99 99 99 99 99 c9 3f 00 00 00 00 00
00 08 c0 9a 99 99 99 99 99 01 c0 cd cc cc cc cc
cc f4 bf 33 33 33 33 33 33 11 40 cd cc cc cc cc
cc 00 40 9a 99 99 99 99 99 b9 3f 33 33 33 33 33
33 f3 bf 33 33 33 33 33 33 0b 40 66 66 66 66 66
66 16 c0
Output File: output_multiple_objects_3d.bin
03 00 00 00 74 03 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08
40 00 00 00 00 00 00 08 40 00 00 00 00 00 00 10
40 00 00 00 00 00 00 14 40 00 00 00 00 00 00 14
40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0
3f 6c 02 00 00 00 00 00 00 00 00 00 f0 3f 00 00
00 00 00 00 00 40 00 00 00 00 00 00 08 40 00 00
00 00 00 00 08 40 00 00 00 00 00 00 10 40 00 00
00 00 00 00 14 40 70 05 00 00 00 00 00 00 00 00
00 f0 3f 00 00 00 00 00 00 00 00 00 00 00 00 00
00 f0 bf 00 00 00 00 00 00 00 40 9a 99 99 99 99
99 f1 3f 9a 99 99 99 99 99 c9 3f 00 00 00 00 00
00 08 c0 9a 99 99 99 99 99 01 c0 cd cc cc cc cc
cc f4 bf 33 33 33 33 33 33 11 40 cd cc cc cc cc
cc 00 40 9a 99 99 99 99 99 b9 3f 33 33 33 33 33
33 f3 bf 33 33 33 33 33 33 0b 40 66 66 66 66 66
66 16 c0
Terminal:
$ ./a.out input_multiple_3d.bin output_multiple_3d.bin
03 00 00 00 74 03 00 00 00 00 00 00 00 00 00 f0
3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00 08
40 00 00 00 00 00 00 08 40 00 00 00 00 00 00 10
40 00 00 00 00 00 00 14 40 00 00 00 00 00 00 14
40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0
3f 6c 02 00 00 00 00 00 00 00 00 00 f0 3f 00 00
00 00 00 00 00 40 00 00 00 00 00 00 08 40 00 00
00 00 00 00 08 40 00 00 00 00 00 00 10 40 00 00
00 00 00 00 14 40 70 05 00 00 00 00 00 00 00 00
00 f0 3f 00 00 00 00 00 00 00 00 00 00 00 00 00
00 f0 bf 00 00 00 00 00 00 00 40 9a 99 99 99 99
99 f1 3f 9a 99 99 99 99 99 c9 3f 00 00 00 00 00
00 08 c0 9a 99 99 99 99 99 01 c0 cd cc cc cc cc
cc f4 bf 33 33 33 33 33 33 11 40 cd cc cc cc cc
cc 00 40 9a 99 99 99 99 99 b9 3f 33 33 33 33 33
33 f3 bf 33 33 33 33 33 33 0b 40 66 66 66 66 66
66 16 c0
$
Pseudo Code
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <exception>
#include <iomanip>
using namespace std;
class Geometry_ND;
class Point_ND
{
private:
vector<double> m_coords;
unsigned m_dim;
friend class Geometry_ND;
public:
// Constructor, initializes dimension and coordinates
Point_ND(const unsigned &arg_dim = 2);
// Copy constructor
Point_ND(const Point_ND &arg_point);
// assignment operator
Point_ND &operator=(const Point_ND &arg_point);
// get coordinates
vector<double> get_coords() const;
// get dimension
unsigned get_dim() const;
// set coordinates
void set_coords(const vector<double> &arg_coords);
// write data members in binary format
void write_binary_coords(ofstream &arg_ofs);
// read data members in binary format
void read_binary_coords(ifstream &arg_ifs);
// friend class
friend class Geometry_ND;
};
class Geometry_ND
{
protected:
// data members
vector<Point_ND> m_point_array;
unsigned m_dim;
public:
// Constructor, initializes the array
Geometry_ND(const unsigned &arg_dim = 2,
const unsigned int &arg_num_of_vertex = 0);
// Copy constructor
Geometry_ND(const Geometry_ND &arg_geometry);
// assignment operator
Geometry_ND &operator=(const Geometry_ND &arg_geometry);
// print the geometry
virtual void print_geometry(ofstream &arg_ofs);
// parse the cin to the geometry
virtual void parse_geometry(ifstream &arg_ifs);
// set the geometry
void set_geometry(const vector<Point_ND> &arg_point_array);
// get the geometry array
vector<Point_ND> get_geometry_array();
};
class Triangle_ND : public Geometry_ND
{
public:
// Constructor, initializes the array
Triangle_ND(const unsigned &arg_dim = 2);
// Copy constructor
Triangle_ND(const Triangle_ND &arg_triangle);
// assignment operator
Triangle_ND &operator=(const Triangle_ND &arg_triangle);
// print the geometry
void print_geometry(ofstream &arg_ofs);
// parse the cin to the geometry
void parse_geometry(ifstream &arg_ifs);
};
const unsigned triangle_num_of_vertex = 3;
class Polygon_ND : public Geometry_ND
{
public:
// Constructor, initializes the array
Polygon_ND(const unsigned &arg_dim = 2);
// Copy constructor
Polygon_ND(const Polygon_ND &arg_polygon);
// assignment operator
Polygon_ND &operator=(const Polygon_ND &arg_polygon);
// print the geometry
void print_geometry(ofstream &arg_ofs);
// parse the cin to the geometry
void parse_geometry(ifstream &arg_ifs);
};
class Line_ND : public Geometry_ND
{
public:
// Constructor, initializes the array
Line_ND(const unsigned &arg_dim = 2);
// Copy constructor
Line_ND(const Line_ND &arg_line);
// assignment operator
Line_ND &operator=(const Line_ND &arg_line);
// print the geometry
void print_geometry(ofstream &arg_ofs);
// parse the cin to the geometry
void parse_geometry(ifstream &arg_ifs);
};
const unsigned line_num_of_vertex = 2;
// Ref: https://stackoverflow.com/q/9621893
void print_output_file(int argc, char *argv[])
{
ifstream ans_ifs(argv[2], ios::in | ios::binary);
if (!ans_ifs)
{
cout << "Error: Cannot open output file" << endl;
exit(1);
}
char ans_block = 0;
unsigned offset_count = 0;
ans_ifs.read(&ans_block, 1);
while (!ans_ifs.eof())
{
int z = ans_block & 0xff;
cout << std::hex
<< std::setfill('0')
<< std::setw(2)
<< z
<< " ";
offset_count++;
if (offset_count % 16 == 0)
{
cout << endl;
}
ans_ifs.read(&ans_block, 1);
}
cout << endl;
ans_ifs.close();
}
int main(int argc, char *argv[])
{
vector<Geometry_ND *> geo_ptr_array;
string input_file_path(argv[1]);
string output_file_path(argv[2]);
char input;
unsigned dim;
Geometry_ND *geo_ptr;
// open the input file
ifstream infile(input_file_path, ios::in | ios::binary);
// open the output file
ofstream outfile(output_file_path, ios::out | ios::trunc | ios::binary);
// read dimension
// read geometry
while (infile.get(input))
{
// check the geometry type
switch (input)
{
case 't':
geo_ptr = new Triangle_ND(dim);
break;
case 'p':
geo_ptr = new Polygon_ND(dim);
break;
case 'l':
geo_ptr = new Line_ND(dim);
break;
}
if (input == 't' || input == 'p' || input == 'l')
{
// parse the infile to the geometry
geo_ptr->parse_geometry(infile);
// push the pointer to the array
geo_ptr_array.push_back(geo_ptr);
}
}
// print the geometry
// first, print the dimension
// second, print the geometry
for (int i = 0; i < geo_ptr_array.size(); i++)
{
geo_ptr_array[i]->print_geometry(outfile);
}
// close the input & output file
infile.close();
outfile.close();
// delete the geometry
for (int i = 0; i < geo_ptr_array.size(); i++)
{
delete geo_ptr_array[i];
}
print_output_file(argc, argv);
return 0;
}
Reference Code:
TA
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <exception>
#include <iomanip>
using namespace std;
class Geometry_ND;
class Point_ND
{
private:
vector<double> m_coords;
unsigned m_dim;
friend class Geometry_ND;
public:
// Constructor, initializes the array
Point_ND(const unsigned &arg_dim = 2);
// Copy constructor
Point_ND(const Point_ND &arg_point);
// assignment operator
Point_ND &operator=(const Point_ND &arg_point);
// get coordinates
vector<double> get_coords() const;
// get dimension
unsigned get_dim() const;
// set coordinates
void set_coords(const vector<double> &arg_coords);
// write data members in binary format
void write_binary_coords(ofstream &arg_ofs);
// read data members in binary format
void read_binary_coords(ifstream &arg_ifs);
// friend class
friend class Geometry_ND;
};
class Geometry_ND
{
protected:
// data members
vector<Point_ND> m_point_array;
unsigned m_dim;
public:
// Constructor, initializes the array
Geometry_ND(const unsigned &arg_dim = 2,
const unsigned int &arg_num_of_vertex = 0);
// Copy constructor
Geometry_ND(const Geometry_ND &arg_geometry);
// assignment operator
Geometry_ND &operator=(const Geometry_ND &arg_geometry);
// print the geometry
virtual void print_geometry(ofstream &arg_ofs);
// parse the cin to the geometry
virtual void parse_geometry(ifstream &arg_ifs);
// set the geometry
void set_geometry(const vector<Point_ND> &arg_point_array);
// get the geometry array
vector<Point_ND> get_geometry_array();
};
class Triangle_ND : public Geometry_ND
{
public:
// Constructor, initializes the array
Triangle_ND(const unsigned &arg_dim = 2);
// Copy constructor
Triangle_ND(const Triangle_ND &arg_triangle);
// assignment operator
Triangle_ND &operator=(const Triangle_ND &arg_triangle);
// print the geometry
void print_geometry(ofstream &arg_ofs);
// parse the cin to the geometry
void parse_geometry(ifstream &arg_ifs);
};
const unsigned triangle_num_of_vertex = 3;
class Polygon_ND : public Geometry_ND
{
public:
// Constructor, initializes the array
Polygon_ND(const unsigned &arg_dim = 2);
// Copy constructor
Polygon_ND(const Polygon_ND &arg_polygon);
// assignment operator
Polygon_ND &operator=(const Polygon_ND &arg_polygon);
// print the geometry
void print_geometry(ofstream &arg_ofs);
// parse the cin to the geometry
void parse_geometry(ifstream &arg_ifs);
};
class Line_ND : public Geometry_ND
{
public:
// Constructor, initializes the array
Line_ND(const unsigned &arg_dim = 2);
// Copy constructor
Line_ND(const Line_ND &arg_line);
// assignment operator
Line_ND &operator=(const Line_ND &arg_line);
// print the geometry
void print_geometry(ofstream &arg_ofs);
// parse the cin to the geometry
void parse_geometry(ifstream &arg_ifs);
};
const unsigned line_num_of_vertex = 2;
// Ref: https://stackoverflow.com/q/9621893
void print_output_file(int argc, char *argv[])
{
ifstream ans_ifs(argv[2], ios::in | ios::binary);
if (!ans_ifs)
{
cout << "Error: Cannot open output file" << endl;
exit(1);
}
char ans_block = 0;
unsigned offset_count = 0;
ans_ifs.read(&ans_block, 1);
while (!ans_ifs.eof())
{
int z = ans_block & 0xff;
cout << std::hex
<< std::setfill('0')
<< std::setw(2)
<< z
<< " ";
offset_count++;
if (offset_count % 16 == 0)
{
cout << endl;
}
ans_ifs.read(&ans_block, 1);
}
cout << endl;
ans_ifs.close();
}
// Point_ND class implementation
// Constructor
Point_ND::Point_ND(const unsigned &arg_dim)
: m_dim(arg_dim), m_coords(arg_dim)
{
}
// Copy constructor
Point_ND::Point_ND(const Point_ND &arg_point)
: m_dim(arg_point.m_dim), m_coords(arg_point.m_coords)
{
}
// assignment operator
Point_ND &Point_ND::operator=(const Point_ND &arg_point)
{
if (this != &arg_point)
{
m_dim = arg_point.m_dim;
m_coords = arg_point.m_coords;
}
return *this;
}
// get dimension
unsigned Point_ND::get_dim() const
{
return m_dim;
}
// get coordinates
vector<double> Point_ND::get_coords() const
{
return m_coords;
}
// set coordinates
void Point_ND::set_coords(const vector<double> &arg_coords)
{
m_coords = arg_coords;
}
// write data members in binary format
void Point_ND::write_binary_coords(ofstream &arg_ofs)
{
for (unsigned i = 0; i < m_dim; i++)
{
arg_ofs.write((char *)&m_coords[i], sizeof(double));
}
}
// read data members in binary format
void Point_ND::read_binary_coords(ifstream &arg_ifs)
{
double temp_double;
for (unsigned i = 0; i < m_dim; i++)
{
arg_ifs.read((char *)&temp_double, sizeof(double));
m_coords[i] = temp_double;
}
}
// Geometry_ND class implementation
// Constructor, initializes the array
Geometry_ND::Geometry_ND(const unsigned &arg_dim, const unsigned int &arg_num_of_vertex)
: m_dim(arg_dim), m_point_array(arg_num_of_vertex)
{
}
// Copy constructor
Geometry_ND::Geometry_ND(const Geometry_ND &arg_geometry)
: m_dim(arg_geometry.m_dim), m_point_array(arg_geometry.m_point_array)
{
}
// assignment operator
Geometry_ND &Geometry_ND::operator=(const Geometry_ND &arg_geometry)
{
if (this == &arg_geometry) // self-assignment
return *this;
m_point_array = arg_geometry.m_point_array;
return *this;
}
// print the geometry
void Geometry_ND::print_geometry(ofstream &arg_ofs)
{
throw runtime_error("print_geometry() is not implemented");
}
// parse the cin to the geometry
void Geometry_ND::parse_geometry(ifstream &arg_ifs)
{
throw runtime_error("parse_geometry() is not implemented");
}
// set the geometry
void Geometry_ND::set_geometry(const vector<Point_ND> &arg_point_array)
{
// check the dimension
for (unsigned i = 0; i < arg_point_array.size(); i++)
{
if (arg_point_array[i].get_dim() != m_dim)
{
throw runtime_error("The dimension of the geometry is not consistent");
}
}
m_point_array = arg_point_array;
}
// get the geometry array
vector<Point_ND> Geometry_ND::get_geometry_array()
{
return m_point_array;
}
// Triangle_ND class implementation
// Constructor, initializes the array
Triangle_ND::Triangle_ND(const unsigned &arg_dim)
: Geometry_ND(arg_dim, triangle_num_of_vertex)
{
}
// Copy constructor
Triangle_ND::Triangle_ND(const Triangle_ND &arg_triangle)
: Geometry_ND(arg_triangle)
{
}
// assignment operator
Triangle_ND &Triangle_ND::operator=(const Triangle_ND &arg_triangle)
{
if (this == &arg_triangle) // self-assignment
return *this;
Geometry_ND::operator=(arg_triangle);
return *this;
}
// print the geometry
void Triangle_ND::print_geometry(ofstream &arg_ofs)
{
unsigned num_of_vertex = m_point_array.size();
arg_ofs.write("t", 1);
arg_ofs.write((char *)&num_of_vertex, sizeof(unsigned int));
for (int i = 0; i < num_of_vertex; i++)
{
m_point_array[i].write_binary_coords(arg_ofs);
}
}
// parse the cin to the geometry
void Triangle_ND::parse_geometry(ifstream &arg_ifs)
{
unsigned int vertex_num;
arg_ifs.read((char *)&vertex_num, sizeof(unsigned int));
if (vertex_num != triangle_num_of_vertex)
{
throw runtime_error("Triangle_ND::parse_geometry(): wrong vertex number");
}
for (int i = 0; i < vertex_num; i++)
{
Point_ND point(m_dim);
point.read_binary_coords(arg_ifs);
m_point_array[i] = point;
}
}
// Polygon_ND class implementation
// Constructor, initializes the array
Polygon_ND::Polygon_ND(const unsigned &arg_dim)
: Geometry_ND(arg_dim)
{
}
// Copy constructor
Polygon_ND::Polygon_ND(const Polygon_ND &arg_polygon)
: Geometry_ND(arg_polygon)
{
}
// assignment operator
Polygon_ND &Polygon_ND::operator=(const Polygon_ND &arg_polygon)
{
if (this == &arg_polygon) // self-assignment
return *this;
Geometry_ND::operator=(arg_polygon);
return *this;
}
// print the geometry
void Polygon_ND::print_geometry(ofstream &arg_ofs)
{
unsigned num_of_vertex = m_point_array.size();
arg_ofs.write("p", 1);
arg_ofs.write((char *)&num_of_vertex, sizeof(unsigned int));
for (int i = 0; i < num_of_vertex; i++)
{
m_point_array[i].write_binary_coords(arg_ofs);
}
}
// parse the cin to the geometry
void Polygon_ND::parse_geometry(ifstream &arg_ifs)
{
unsigned int vertex_num;
arg_ifs.read((char *)&vertex_num, sizeof(unsigned int));
if (vertex_num < 3)
{
throw runtime_error("Polygon_ND::parse_geometry(): wrong vertex number");
}
m_point_array.resize(vertex_num);
for (int i = 0; i < vertex_num; i++)
{
Point_ND point(m_dim);
point.read_binary_coords(arg_ifs);
m_point_array[i] = point;
}
}
// Line_ND class implementation
// Constructor, initializes the array
Line_ND::Line_ND(const unsigned &arg_dim)
: Geometry_ND(arg_dim, line_num_of_vertex)
{
}
// Copy constructor
Line_ND::Line_ND(const Line_ND &arg_line)
: Geometry_ND(arg_line)
{
}
// assignment operator
Line_ND &Line_ND::operator=(const Line_ND &arg_line)
{
if (this == &arg_line) // self-assignment
return *this;
Geometry_ND::operator=(arg_line);
return *this;
}
// print the geometry
void Line_ND::print_geometry(ofstream &arg_ofs)
{
unsigned num_of_vertex = m_point_array.size();
arg_ofs.write("l", 1);
arg_ofs.write((char *)&num_of_vertex, sizeof(unsigned int));
for (int i = 0; i < num_of_vertex; i++)
{
m_point_array[i].write_binary_coords(arg_ofs);
}
}
// parse the cin to the geometry
void Line_ND::parse_geometry(ifstream &arg_ifs)
{
unsigned int vertex_num;
arg_ifs.read((char *)&vertex_num, sizeof(unsigned int));
if (vertex_num != line_num_of_vertex)
{
throw runtime_error("Line_ND::parse_geometry(): wrong vertex number");
}
for (int i = 0; i < vertex_num; i++)
{
Point_ND point(m_dim);
point.read_binary_coords(arg_ifs);
m_point_array[i] = point;
}
}
int main(int argc, char *argv[])
{
vector<Geometry_ND *> geo_ptr_array;
string input_file_path(argv[1]);
string output_file_path(argv[2]);
try
{
char input;
unsigned dim;
Geometry_ND *geo_ptr;
// open the input file
ifstream infile(input_file_path, ios::in | ios::binary);
infile.exceptions(ios::badbit);
// open the output file
ofstream outfile(output_file_path, ios::out | ios::trunc | ios::binary);
outfile.exceptions(ios::badbit);
// read dimension
infile.read((char *)&dim, sizeof(unsigned));
if (dim < 2 || dim > 10)
{
throw runtime_error("main(): wrong dimension");
}
// read geometry
while (infile.get(input))
{
// check the geometry type
switch (input)
{
case 't':
geo_ptr = new Triangle_ND(dim);
break;
case 'p':
geo_ptr = new Polygon_ND(dim);
break;
case 'l':
geo_ptr = new Line_ND(dim);
break;
default:
throw runtime_error("main(): wrong geometry type");
}
if (input == 't' || input == 'p' || input == 'l')
{
// change exception mask
infile.exceptions(ios::badbit | ios::failbit | ios::eofbit);
// parse the infile to the geometry
geo_ptr->parse_geometry(infile);
// push the pointer to the array
geo_ptr_array.push_back(geo_ptr);
// rollback the exception mask
infile.exceptions(ios::badbit);
}
else
{
throw runtime_error("main(): wrong geometry type");
}
}
// print the geometry
// first, print the dimension
outfile.write((char *)&dim, sizeof(unsigned));
// second, print the geometry
for (int i = 0; i < geo_ptr_array.size(); i++)
{
geo_ptr_array[i]->print_geometry(outfile);
}
// close the input & output file
infile.close();
outfile.close();
}
catch (exception &e)
{
cout << e.what() << endl;
// delete the geometry
for (int i = 0; i < geo_ptr_array.size(); i++)
{
delete geo_ptr_array[i];
}
return 1;
}
// delete the geometry
for (int i = 0; i < geo_ptr_array.size(); i++)
{
delete geo_ptr_array[i];
}
print_output_file(argc, argv);
return 0;
}
Convert Text Version Input to Binary Version Input
/*** convert text version input to binary version input ***/
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
// error and exit
void error_and_exit()
{
cout << "Error: Invalid input" << endl;
exit(1);
}
int main(int argc, char *argv[])
{
if (argc != 3)
{
cout << "Usage: txt_to_bin <input_file> <output_file>" << endl;
return 1;
}
ifstream input_file(argv[1]);
ofstream output_file(argv[2], ios::binary | ios::trunc);
if (!input_file.is_open())
{
cout << "Could not open input file" << endl;
return 1;
}
if (!output_file.is_open())
{
cout << "Could not open output file" << endl;
return 1;
}
string line, temp;
unsigned num_of_vertices = 1;
// read dimensions
getline(input_file, line);
unsigned num_of_dimensions = stoul(line);
// write dimensions
output_file.write((char *)&num_of_dimensions, sizeof(unsigned));
while (getline(input_file, line))
{
// check the geometry type
switch (line[0])
{
case 't':
case 'p':
case 'l':
// get the number of vertices from the next line
getline(input_file, temp);
num_of_vertices = stoul(temp);
break;
default:
error_and_exit();
}
// write the geometry type
char geometry_type = line[0];
output_file.write(&geometry_type, 1);
// write the number of vertices
if (line[0] == 't' || line[0] == 'p' || line[0] == 'l')
{
output_file.write((char *)&num_of_vertices, sizeof(unsigned));
}
// convert the lines to binary
for (int i = 0; i < num_of_vertices; i++)
{
getline(input_file, line);
stringstream ss(line);
for (int j = 0; j < num_of_dimensions; j++)
{
getline(ss, temp, ',');
double value = stod(temp);
output_file.write((char *)&value, sizeof(double));
}
}
}
input_file.close();
output_file.close();
return 0;
}
Convert Binary Version Input/Output to Human-readable Input/Output & Dump HEX File
/*** convert binary version input to human-readable input & dump hex file ***/
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;
// error and exit
void error_and_exit()
{
cout << "Error: Invalid input" << endl;
exit(1);
}
int main(int argc, char *argv[])
{
if (argc != 3)
{
cout << "Usage: bin_to_txt <input_file> <output_file>" << endl;
return 1;
}
ifstream input_file(argv[1], ios::binary);
ofstream output_file(argv[2], ios::trunc);
if (!input_file.is_open())
{
cout << "Could not open input file" << endl;
return 1;
}
if (!output_file.is_open())
{
cout << "Could not open output file" << endl;
return 1;
}
char input;
unsigned num_of_vertices = 1;
// read dimensions
unsigned num_of_dimensions = 2;
input_file.read((char *)&num_of_dimensions, sizeof(unsigned));
// write dimensions
output_file << "# " << num_of_dimensions << endl;
while (input_file.get(input))
{
// check the geometry type
switch (input)
{
case 't':
case 'p':
case 'l':
// get the number of vertices from the next line
input_file.read((char *)&num_of_vertices, sizeof(unsigned));
break;
default:
error_and_exit();
}
// write the geometry type
char geometry_type = input;
output_file << "# " << geometry_type << endl;
// write the number of vertices
if (geometry_type == 't' || geometry_type == 'p' || geometry_type == 'l')
{
output_file << "# " << num_of_vertices << endl;
}
// convert the lines to human-readable format
for (int i = 0; i < num_of_vertices; i++)
{
output_file << "# " << setprecision(15) << fixed;
for (int j = 0; j < num_of_dimensions; j++)
{
double temp;
input_file.read((char *)&temp, sizeof(double));
if (j != 0)
{
output_file << ",";
}
output_file << temp;
}
output_file << endl;
}
}
input_file.close();
input_file.open(argv[1], ios::binary);
output_file << "# Hex dump" << endl;
char file_block = 0;
unsigned offset_count = 0;
input_file.read(&file_block, 1);
while (!input_file.eof())
{
int z = file_block & 0xff;
output_file << std::hex
<< std::setfill('0')
<< std::setw(2)
<< z
<< " ";
offset_count++;
if (offset_count % 16 == 0)
{
output_file << endl;
}
input_file.read(&file_block, 1);
}
output_file << endl;
output_file.close();
return 0;
}