Quindi ho il seguente Leggo in linee da un file di testo. Ogni riga deve essere analizzata e ottenere i dati importanti estratti (non andrò nei dettagli qui).
Ho creato una classe Parser che fa questo lavoro. Unforunately può accadere abbastanza frequentemente, che i dati di linea non sono utilizzabili. Lo trovo solo quando leggo la riga nella classe e lo analizzo. Così ho fatto un bit valido che indica se i dati sono ok. Al momento controllo il bit valido prima di prendere i dati. Mi stavo chiedendo se è una pratica migliore qui per lanciare un'eccezione. D'altra parte ho sentito solo eccezioni quando il caso non si verifica frequentemente. Nel mio caso, come metà delle righe che analizzo con la classe Parser non sono dati validi.
Ecco un codice incompleto semplificato su come è stato fatto adesso per ottenere l'idea:
struct Symbol_data { // possible data which can be extracted out of the symbolik
//Struct with the extracted data...
};
class Parse_symbol_line { //class extracts data from a line. it is possible the data is unsusable
public:
Parse_symbol_line(std::string& l);
bool is_valid() const { return valid; } //during processing the data can become unusable
Symbol_data get_symbolic_data() { return sym_data; }
private:
//Private Methods here which extract and analyse the line in many steps
void read_data_from_line();
void analyze_raw_comment();
void mask_out_device_id();
void analyze_device_id();
void mask_out_vessel();
void create_symbol_data();
bool valid; // if in valid dont use the data
Symbol_data sym_data;
};
//constructor calls all the steps to read out the data out of the line
//it is possible after each step, that the line is not valid and therefore doesnt need more checks
Parse_symbol_line::Parse_symbol_line(std::string& l)
:valid{ true }, EA{ true }, line{ l }, sym_data{ Symbol_data{} }
{
read_raw_data_from_line();
if (!valid) return; //dont continue if data is invalid anyway
analyze_raw_comment();
if (!valid) return;
mask_out_device_id();
if (!valid) return;
analyze_device_id();
if (!valid) return;
mask_out_vessel();
if (!valid) return;
create_symbol_data();
if (!valid) return;
}
//another class provides the lines to the parse class and gets the data from it
void Compute_Symbols::read_symbolic()
{
std::ifstream ifs{ in_sym_fname };
if (!ifs) throw std::runtime_error("void Compute_Symbols::read_symbolic(); symbolic file could not be opened\n");
for (std::string line; std::getline(ifs, line);) {
Parse_symbol_line psl{ line };
if (psl.is_valid()) {
//continue work with the data
}
else if (!psl.is_valid()) {
//dont use the data
}
}
}