add lab3
This commit is contained in:
224
lab3/grid2DIO.cpp
Normal file
224
lab3/grid2DIO.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
// Functions to read/write a 2D grid of 3D points.
|
||||
|
||||
#include "grid2DIO.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
const std::string GRID2D_POINTS3D_HEADER = "GRID2D_OF_POINTS3D";
|
||||
|
||||
|
||||
// ********************************************************************************
|
||||
// Internal helpers
|
||||
// ********************************************************************************
|
||||
|
||||
/// Trim leading and trailing whitespace from s.
|
||||
static std::string Trim(const std::string& s) {
|
||||
const std::string whitespace = " \t\r\n";
|
||||
size_t start = s.find_first_not_of(whitespace);
|
||||
if (start == std::string::npos) { return ""; }
|
||||
size_t end = s.find_last_not_of(whitespace);
|
||||
return s.substr(start, end - start + 1);
|
||||
}
|
||||
|
||||
|
||||
/// Throw a read error with two descriptive lines.
|
||||
static void RaiseReadErrorII(int iline,
|
||||
const std::string& error_line1,
|
||||
const std::string& error_line2)
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"Error reading line " + std::to_string(iline) + ": " +
|
||||
error_line1 + "\n " + error_line2);
|
||||
}
|
||||
|
||||
|
||||
// ********************************************************************************
|
||||
// Read/Write helper predicates
|
||||
// ********************************************************************************
|
||||
|
||||
bool IsHeader(const std::string& line) {
|
||||
return Trim(line) == GRID2D_POINTS3D_HEADER;
|
||||
}
|
||||
|
||||
|
||||
bool IsCommentOrBlankLine(const std::string& line) {
|
||||
std::string s = Trim(line);
|
||||
if (s.empty()) { return true; }
|
||||
if (s[0] == '#') { return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ********************************************************************************
|
||||
// Read functions
|
||||
// ********************************************************************************
|
||||
|
||||
void ReadGrid2DPoints3D(std::istream& infile, GRID2D_POINTS3D& grid2D) {
|
||||
// Read coordinates of point [i,j] in grid.
|
||||
int i = 0, j = 0, iline = 1;
|
||||
std::string line;
|
||||
|
||||
while (std::getline(infile, line)) {
|
||||
std::string trimmed = Trim(line);
|
||||
|
||||
if (iline == 1) {
|
||||
if (!IsHeader(trimmed)) {
|
||||
RaiseReadErrorII(1,
|
||||
"Incorrect file header.",
|
||||
"Expected header: " + GRID2D_POINTS3D_HEADER);
|
||||
}
|
||||
}
|
||||
else if (!IsCommentOrBlankLine(trimmed)) {
|
||||
if (!grid2D.AreDimensionsSet()) {
|
||||
std::istringstream iss(trimmed);
|
||||
int n, m;
|
||||
if (!(iss >> n >> m)) {
|
||||
RaiseReadErrorII(iline,
|
||||
"Incorrect grid dimensions.",
|
||||
"Expecting two integers for grid dimensions.");
|
||||
}
|
||||
std::string extra;
|
||||
if (iss >> extra) {
|
||||
RaiseReadErrorII(iline,
|
||||
"Incorrect grid dimensions.",
|
||||
"Expecting two integers for grid dimensions.");
|
||||
}
|
||||
grid2D.SetDimensions(n, m);
|
||||
}
|
||||
else {
|
||||
std::istringstream iss(trimmed);
|
||||
double x, y, z;
|
||||
if (!(iss >> x >> y >> z)) {
|
||||
RaiseReadErrorII(iline,
|
||||
"Error reading point coordinates.",
|
||||
"Expecting three float coordinates for each point.");
|
||||
}
|
||||
|
||||
if (i >= grid2D.NumRows()) {
|
||||
std::cerr << "Warning: More than "
|
||||
<< grid2D.NumRows() << " x "
|
||||
<< grid2D.NumCols()
|
||||
<< " points in file.\n";
|
||||
std::cerr << "Skipping remaining points after line "
|
||||
<< iline << ".\n";
|
||||
break;
|
||||
}
|
||||
|
||||
grid2D.SetCoord(i, j, x, y, z);
|
||||
|
||||
j++;
|
||||
if (j >= grid2D.NumCols()) {
|
||||
j = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iline++;
|
||||
}
|
||||
|
||||
if (i < grid2D.NumRows()) {
|
||||
throw std::runtime_error(
|
||||
"Too few points in file. Expected coordinates of " +
|
||||
std::to_string(grid2D.NumPoints()) + " points.\n" +
|
||||
" Found coordinates of " +
|
||||
std::to_string(i * grid2D.NumCols() + j) + " points.\n" +
|
||||
" First missing point: [" +
|
||||
std::to_string(i) + "," + std::to_string(j) + "].");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OpenReadGrid2DPoints3D(const std::string& filename,
|
||||
GRID2D_POINTS3D& grid2D)
|
||||
{
|
||||
try {
|
||||
std::ifstream infile(filename);
|
||||
if (!infile.is_open()) {
|
||||
std::cerr << "Input file " << filename << " not found.\n";
|
||||
throw std::runtime_error(
|
||||
"Input file " + filename + " not found.");
|
||||
}
|
||||
ReadGrid2DPoints3D(infile, grid2D);
|
||||
}
|
||||
catch (const std::out_of_range& e) {
|
||||
std::cerr << "Error reading file " << filename
|
||||
<< ".\n " << e.what() << "\n";
|
||||
throw;
|
||||
}
|
||||
catch (const std::runtime_error& e) {
|
||||
std::cerr << "Error reading file " << filename
|
||||
<< ".\n " << e.what() << "\n";
|
||||
throw;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "Error reading file " << filename
|
||||
<< ".\n " << e.what() << "\n";
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ********************************************************************************
|
||||
// Write functions
|
||||
// ********************************************************************************
|
||||
|
||||
void WriteGrid2DPoints3D(std::ostream& outfile,
|
||||
const GRID2D_POINTS3D& grid2D,
|
||||
const std::vector<std::string>& comment_list)
|
||||
{
|
||||
// Write header
|
||||
outfile << GRID2D_POINTS3D_HEADER << "\n";
|
||||
|
||||
// Write dimensions
|
||||
outfile << grid2D.NumRows() << " " << grid2D.NumCols() << "\n";
|
||||
|
||||
// Write comments
|
||||
for (const auto& comment : comment_list) {
|
||||
outfile << "# " << comment << "\n";
|
||||
}
|
||||
|
||||
// Write point coordinates
|
||||
for (int irow = 0; irow < grid2D.NumRows(); irow++) {
|
||||
for (int icol = 0; icol < grid2D.NumCols(); icol++) {
|
||||
auto c = grid2D.Coord(irow, icol);
|
||||
outfile << c[0] << " " << c[1] << " " << c[2] << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OpenWriteGrid2DPoints3D(const std::string& filename,
|
||||
const GRID2D_POINTS3D& grid2D,
|
||||
const std::vector<std::string>& comment_list)
|
||||
{
|
||||
try {
|
||||
std::ofstream outfile(filename);
|
||||
if (!outfile.is_open()) {
|
||||
std::cerr << "Cannot open file " << filename
|
||||
<< " for writing.\n";
|
||||
throw std::runtime_error(
|
||||
"Cannot open file " + filename + " for writing.");
|
||||
}
|
||||
WriteGrid2DPoints3D(outfile, grid2D, comment_list);
|
||||
}
|
||||
catch (const std::out_of_range& e) {
|
||||
std::cerr << "Error writing file " << filename
|
||||
<< ".\n " << e.what() << "\n";
|
||||
throw;
|
||||
}
|
||||
catch (const std::runtime_error& e) {
|
||||
std::cerr << "Error writing file " << filename
|
||||
<< ".\n " << e.what() << "\n";
|
||||
throw;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "Error writing file " << filename
|
||||
<< ".\n " << e.what() << "\n";
|
||||
throw;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user