@laserlight -
Actually the staff said we mustn't use regex.
As for Maxima - I meant, if you can show me how to change the pattern to also define maximums/minimums.
As for exceptions - Yea, I'm pretty sure the our next class will cover the topic of exceptions in CPP. And I understood, in this case you verified at first you have the correct pattern which involves the digits - so nothing is gonna be wrong.
As for emplace - We haven't learnt yet those smart pointers (unique_ptr/shared_ptr).
But, to my understanding, I have nothing to delete here manually (and through all the project in general, because all the allocated data involved here is created inside a vector/stack). These containers receive the pointer to the right Fractal - and they have to destruct it at the end.
No?
File extension - thanks for the remarks!
@john.c -
blank_lines: Yea - I won't change anything to make it fit to only one empty line - this parsing is really overrated. Thanks for the remarks!
2. So you actually add '!' (!(sin >> dim)) to make it be like: sin.fail() and not !sin.fail() as it automatically becomes.
3. So, I understood correctly the process (?) - except for using the EOF word incorrectly.
So, this is the final version:
Code:
#include <iostream>
#include "Fractal.h"
#include <fstream>
#include <stack>
#include <sstream>
const char *usgErr = "Usage: FractalDrawer <file path>\n";
const char *invalidErr = "Invalid input\n";
const char *VALIDEXT = "csv";
const char EXTDOT = '.';
const char COMMA = ',';
const char MINTYPE = 1;
const char MAXTYPE = 3;
const int MINDIM = 1;
const int MAXDIM = 6;
const int NUBEROFARGS = 2;
int main(int argc, char *argv[])
{
if (argc != NUBEROFARGS)
{
std::cerr << usgErr;
std::exit(EXIT_FAILURE);
}
std::string filepath = argv[1];
auto pos = filepath.find_last_of(EXTDOT);
if (pos == std::string::npos || filepath.substr(pos + 1) != VALIDEXT)
{
std::cerr << invalidErr;
exit(EXIT_FAILURE);
}
std::ifstream in(filepath);
std::stack<Fractal *> resToPrint;
bool blank_line_seen = false;
int lineno = 0;
for (std::string line; std::getline(in, line); )
{
std::istringstream sin(line);
++lineno;
int type = 0, dim = 0;
char ch = 0;
if (!(sin >> ch)) // Check if there is some non-whitespace in the current line
{
blank_line_seen = true;
continue;
}
else if (blank_line_seen) // If the current line is non-empty and the previous one was an empty one
{
std::cerr << invalidErr;
exit(EXIT_FAILURE);
}
sin.putback(ch);
if (!(sin >> type) || type < 1 || type > 3) // Take a numeric digit value in legal range
{
std::cerr << invalidErr;
exit(EXIT_FAILURE);
}
if (!(sin >> ch) || ch != COMMA) // The middle char must be a comma
{
std::cerr << invalidErr;
exit(EXIT_FAILURE);
}
if (!(sin >> dim) || dim < 1 || dim > 6) // Take a numeric digit value in legal range
{
std::cerr << invalidErr;
exit(EXIT_FAILURE);
}
if (sin >> ch) // If there is some extra data in the line
{
std::cerr << invalidErr;
exit(EXIT_FAILURE);
}
resToPrint.push(FractalFactory::factoryMethod(type, dim));
}
while (!resToPrint.empty())
{
std::cout << *(resToPrint.top()) << std::endl;
resToPrint.pop();
}
in.close();
return 0;
}
BTW, question regarding this line:
Code:
for(std::string line; std::getline(in, line); )
Here, we only declare on a string, but not allocate some memory for it.
So, how getline succeeds to input something into line?