Final-3: Save Geometry Objects to Binary File & Exception Handling (15%)

  • Inputs:

    1. Read geometry objects from a input file.
      1. Please use int main(int argc, char *argv[]) to open the input file (Ref: One and the only: main function.
      2. The file path of the input file is given as argv[1].
    2. Read the dimensions (dim) of the coordinate system. The dimension is an unsigned between 2 and 10.
    3. Read the type of geometry object in char format with the following types:
      1. l for line
      2. t for triangle
      3. p for polygon
    4. Read the number of vertices in unsigned format for each type of geometry object as shown above.
      1. line: 2
      2. triangle: 3
      3. polygon: \(n \in Z^+, n \ge 3\)
    5. Read the vertices with dim coordinates in double format.
      1. line: <double 1><double 2>...<double dim><double 1><double 2>...<double dim>
      2. triangle: <double 1><double 2>...<double dim><double 1><double 2>...<double dim><double 1><double 2>...<double dim>
      3. polygon: <double 1><double 2>...<double dim><double 1><double 2>...<double dim>...
  • Outputs:

    1. Write geometry objects to a output file.
      1. Please use int main(int argc, char *argv[]) to open the input file (Ref: One and the only: main function.
      2. The file path of the output file is given as argv[2].
    2. Write the dimensions of the coordinate system.
    3. Write all geometric objects in the input, with the following information:
      1. Write the type of the object, the number of vertices, and the vertices.
        1. The format shold follow the descriptions in Format.
        2. The order of the vertices and coordinates should be the same as the input.
        3. Each coordinate should be saved with double format.
    4. Write the dimension and all geometric objects after the input is finished, and exit the program.
  • File name: final-3_<student_id>.cpp (e.g. final-3_106062802.cpp)

  • The program will not have any user prompts, only print the result.

  • The program needs to handle the exceptions in Error Handling. Other exceptions will not occur.

  • The program should base on the main & print_output_file function provided in the pseudo code.

  • If the input file is invalid, the program should print the error message Error: Invalid input in the terminal and terminate the program.

  • 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_objects_2d.bin 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 
$

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_objects_3d.bin 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 
$

Error Handling

Wrong dimensions

Input File: input_wrong_dim.bin

# 11
# l
# 2
# 1.000000000000000,2.000000000000000
# 3.000000000000000,4.000000000000000
# Hex dump
0b 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_wrong_dim.bin


Terminal:

$ ./a.out input_wrong_dim.bin output_wrong_dim.bin
Error: Invalid input
$

Wrong type of object

Input File: input_wrong_type.bin

# 3
# u
# 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 75 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_wrong_type.bin


Terminal:

$ ./a.out input_wrong_type.bin output_wrong_type.bin
Error: Invalid input
$

Wrong number of vertices

Case 1

Input File: input_wrong_line_vtx.bin

# 2
# l
# 3
# 1.000000000000000,2.000000000000000
# 3.000000000000000,4.000000000000000
# Hex dump
02 00 00 00 6c 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 

Output File: output_wrong_line_vtx.bin


Terminal:

$ ./a.out input_wrong_line_vtx.bin output_wrong_line_vtx.bin
Error: Invalid input
$

Case 2

Input File: input_wrong_polygon_vtx.bin

# 3
# p
# 2
# 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_wrong_polygon_vtx.bin


Terminal:

$ ./a.out input_wrong_polygon_vtx.bin output_wrong_polygon_vtx.bin
Error: Invalid input
$

Wrong vertex coordinates/vertex amount

Input File: input_wrong_vtx_amount.bin

# 3
# 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_wrong_vtx_amount.bin


Terminal:

$ ./a.out input_wrong_vtx_amount.bin output_wrong_vtx_amount.bin
Error: Invalid input
$

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]);

    // run codes with exception handling

    {
        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
        infile.read((char *)&dim, sizeof(unsigned));
        if ()
        {
        }

        // 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:
            }
            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);
            }
            else
            {
            }
        }
        // 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();
    }
    // catch the exception

    {

        // 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;
}

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]);

    // run codes with exception handling
    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 the exception
    catch (exception &e)
    {
        cout << "Error: Invalid input" << 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;
}