Advertisement
desislava_shunina

zad 1

Mar 25th, 2024
584
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.80 KB | None | 0 0
  1. #include <fstream>
  2. #include <iomanip>
  3. #include <iostream>
  4. #include <sstream>
  5. #pragma warning(disable : 4996)
  6. using std::cout;
  7.  
  8. namespace GlobalConstants
  9. {
  10. const uint16_t MAX_CELL_SIZE = 50 + 1; // for the terminating zero
  11. const uint16_t MAX_CELLS_IN_ROW = 30;
  12. const uint16_t MAX_ROWS_IN_TABLE = 300;
  13. const char TABLE_TAG[] = "table";
  14. const char ROW_TAG[] = "tr";
  15. const char CELL_TAG[] = "td";
  16. const char HEADER_TAG[] = "th";
  17. const char BEGIN_TAG = '<';
  18. const char END_TAG = '>';
  19. const char CLOSE_TAG = '/';
  20. const char HEADER_SYMBOL = '*';
  21. const char EMPTY_SPACE = ' ';
  22. const char CHARACTER_ENTITY[] = "&#";
  23. const uint16_t BUFFER_SIZE = 1024;
  24. const uint8_t MAX_TAG_SIZE = 64;
  25.  
  26. } // namespace GlobalConstants
  27.  
  28. using namespace GlobalConstants;
  29.  
  30. enum class Direction : int8_t
  31. {
  32.     UP = 1,
  33.     DOWN = -1,
  34.     UNKNOWN = 0
  35. };
  36.  
  37. void characterEntityConvert(char *str)
  38. {
  39.     if (!str)
  40.         return;
  41.  
  42.     std::stringstream ss(str);
  43.  
  44.     uint16_t indx = 0;
  45.     char ch;
  46.     uint16_t chConverted;
  47.  
  48.     while (true)
  49.     {
  50.         ch = ss.get();
  51.         if (ss.eof())
  52.             break;
  53.  
  54.         if (ch == CHARACTER_ENTITY[0] && ss.peek() == CHARACTER_ENTITY[1])
  55.         {
  56.             ss.ignore();                     // ignore the the second symbol (#)
  57.             ss >> chConverted;               // get the asci code as int
  58.             str[indx++] = (char)chConverted; // put the char in the new string
  59.             continue;
  60.         }
  61.         str[indx++] = ch; // copy the current char in the new string
  62.     }
  63.     str[indx] = '\0'; // end the string
  64. }
  65.  
  66. struct Cell
  67. {
  68.     char cell[MAX_CELL_SIZE] = {};
  69.     bool isHeader = false;
  70.  
  71.     uint16_t getCellStrLength() const
  72.     {
  73.         return strlen(cell) + 2; // adding 2 spaces on both ends of table
  74.     }
  75.     void printCell(uint16_t allignement) const
  76.     {
  77.         cout << '|';
  78.  
  79.         if (isHeader)
  80.             cout << HEADER_SYMBOL << cell << std::setw(allignement - strlen(cell) - 1) << HEADER_SYMBOL;
  81.         else
  82.             cout << EMPTY_SPACE << cell << std::setw(allignement - strlen(cell) - 1) << EMPTY_SPACE;
  83.     }
  84. };
  85.  
  86. class Row
  87. {
  88.   private:
  89.     Cell cells[MAX_CELLS_IN_ROW] = {};
  90.     uint16_t cellsCount = 0;
  91.  
  92.   public:
  93.     const Cell *getCells() const
  94.     {
  95.         return cells;
  96.     }
  97.     uint16_t getCellsCount() const
  98.     {
  99.         return cellsCount;
  100.     }
  101.  
  102.     Row(const Cell *_cells, uint16_t _cellsCount)
  103.     {
  104.         if (!_cells)
  105.             return;
  106.  
  107.         for (uint16_t i = 0; i < _cellsCount; i++)
  108.             cells[i] = _cells[i];
  109.  
  110.         cellsCount = _cellsCount;
  111.     }
  112.     Row()
  113.     {
  114.         cellsCount = 0;
  115.     }
  116.  
  117.     bool modifyCell(uint16_t index, const char *newValue)
  118.     {
  119.         if (!newValue || index >= cellsCount || strlen(newValue) >= MAX_CELL_SIZE)
  120.             return false;
  121.  
  122.         strcpy(cells[index].cell, newValue);
  123.         return true;
  124.     }
  125.     bool addCellAtBack(const char *value, bool _isHeader)
  126.     {
  127.         if (!value || cellsCount >= MAX_CELLS_IN_ROW || strlen(value) >= MAX_CELL_SIZE)
  128.             return false;
  129.  
  130.         strcpy(cells[cellsCount].cell, value);
  131.         cells[cellsCount++].isHeader = _isHeader;
  132.         return true;
  133.     }
  134. };
  135.  
  136. class Table
  137. {
  138.   private:
  139.     Row rows[MAX_ROWS_IN_TABLE] = {};
  140.     uint16_t rowsCount = 0;
  141.     bool isGood = true;
  142.  
  143.     void shiftRowsDown(uint16_t from)
  144.     {
  145.         for (int16_t i = rowsCount; i > from; i--)
  146.         {
  147.             rows[i] = rows[i - 1];
  148.         }
  149.         rows[from] = {}; // empty the new opened row
  150.         rowsCount++;
  151.     }
  152.     void shiftRowsUp(uint16_t from)
  153.     {
  154.         for (int16_t i = from; i < rowsCount - 1; i++)
  155.         {
  156.             rows[i] = rows[i + 1];
  157.         }
  158.         rows[rowsCount--] = {}; // empty the new opened row at the bottom
  159.     }
  160.     void shiftRows(uint16_t from, Direction dir)
  161.     {
  162.         if (dir == Direction::DOWN)
  163.             shiftRowsDown(from);
  164.         if (dir == Direction::UP)
  165.             shiftRowsUp(from);
  166.     }
  167.     bool getNextTag(char *dest, std::ifstream &ifs) const
  168.     {
  169.         if (!dest || !ifs.good())
  170.             return false;
  171.  
  172.         while (true)
  173.         {
  174.             char ch = ifs.get();
  175.             if (ch == BEGIN_TAG)
  176.             {
  177.                 ifs.getline(dest, MAX_TAG_SIZE, END_TAG);
  178.                 return true;
  179.             }
  180.             if (ifs.eof())
  181.                 return false;
  182.         }
  183.     }
  184.     bool readNextCell(std::ifstream &ifs, bool isHeader)
  185.     {
  186.         char buff[MAX_CELL_SIZE];
  187.         ifs.get(buff, MAX_CELL_SIZE, '<'); // failbit when trying to read empty string
  188.         ifs.clear();
  189.         characterEntityConvert(buff);
  190.         rows[rowsCount].addCellAtBack(buff, isHeader);
  191.         ifs.getline(buff, MAX_CELL_SIZE, '>');
  192.         return true;
  193.     }
  194.     bool readNextRow(std::ifstream &ifs)
  195.     {
  196.         while (true)
  197.         {
  198.             char tag[MAX_TAG_SIZE];
  199.             if (!getNextTag(tag, ifs))
  200.                 return isGood = false;
  201.  
  202.             if (strcmp(tag, CELL_TAG) == 0) // for normal tag
  203.             {
  204.                 readNextCell(ifs, false);
  205.             }
  206.             else if (strcmp(tag, HEADER_TAG) == 0) // for header tag
  207.             {
  208.                 readNextCell(ifs, true);
  209.             }
  210.             else // if the tag is the closing tag , may be better if we do a correctness check
  211.             {
  212.                 rowsCount++;
  213.                 return true;
  214.             }
  215.         }
  216.     }
  217.     void calcColsAlignement(uint16_t colsCount, uint16_t *colsAlignement) const
  218.     {
  219.         for (uint16_t i = 0; i < colsCount; i++)
  220.         {
  221.             colsAlignement[i] = 0;
  222.             for (uint16_t j = 0; j < rowsCount; j++)
  223.             {
  224.                 if (rows[j].getCells()[i].getCellStrLength() > colsAlignement[i])
  225.                     colsAlignement[i] = rows[j].getCells()[i].getCellStrLength();
  226.             }
  227.         }
  228.     }
  229.  
  230.   public:
  231.     const Row *getRows() const
  232.     {
  233.         return rows;
  234.     }
  235.     uint16_t getRowsCount() const
  236.     {
  237.         return rowsCount;
  238.     }
  239.     uint16_t countCols() const
  240.     {
  241.         uint16_t res = 0;
  242.  
  243.         for (size_t i = 0; i < rowsCount; i++)
  244.         {
  245.             if (rows[i].getCellsCount() > res)
  246.                 res = rows[i].getCellsCount();
  247.         }
  248.         return res;
  249.     }
  250.     bool isOk() const
  251.     {
  252.         return isGood;
  253.     }
  254.     void print() const
  255.     {
  256.         uint16_t colsCount = this->countCols();
  257.         uint16_t *colsAlignement = new uint16_t[colsCount];
  258.         this->calcColsAlignement(colsCount, colsAlignement);
  259.  
  260.         for (uint16_t i = 0; i < rowsCount; i++)
  261.         {
  262.             for (uint16_t j = 0; j < colsCount; j++)
  263.             {
  264.                 rows[i].getCells()[j].printCell(colsAlignement[j]);
  265.             }
  266.             cout << "|\n";
  267.         }
  268.  
  269.         delete[] colsAlignement;
  270.     }
  271.  
  272.     bool edit(uint16_t row, uint16_t col, const char *newValue)
  273.     {
  274.         // index for users starts from 1
  275.         row--;
  276.         col--;
  277.  
  278.         if (row >= rowsCount || col >= rows[row].getCellsCount() || !newValue)
  279.             return false;
  280.  
  281.         rows[row].modifyCell(col, newValue);
  282.         return true;
  283.     }
  284.     bool add(uint16_t rowIndex, const Row &newRow)
  285.     {
  286.         rowIndex--; // index for users starts from 1
  287.  
  288.         if (rowIndex >= MAX_ROWS_IN_TABLE)
  289.             return false;
  290.  
  291.         shiftRows(rowIndex, Direction::DOWN);
  292.         rows[rowIndex] = newRow;
  293.         return true;
  294.     }
  295.     bool remove(uint16_t row)
  296.     {
  297.         row--; // index for users starts from 1
  298.         if (row > rowsCount)
  299.             return false;
  300.  
  301.         shiftRows(row, Direction::UP); // using the advantage that the user inputs the rows starting from index 1...
  302.         return true;
  303.     }
  304.  
  305.     Table(const char *fileName)
  306.     {
  307.         if (!fileName)
  308.         {
  309.             isGood = false;
  310.             return;
  311.         }
  312.  
  313.         std::ifstream ifs(fileName);
  314.         if (!ifs.is_open())
  315.         {
  316.             isGood = false;
  317.             return;
  318.         }
  319.  
  320.         while (true)
  321.         {
  322.             char tag[MAX_TAG_SIZE];
  323.             if (!getNextTag(tag, ifs))
  324.                 return;
  325.  
  326.             if (strcmp(tag, ROW_TAG) == 0)
  327.             {
  328.                 if (!readNextRow(ifs))
  329.                 {
  330.                     isGood = false;
  331.                     return;
  332.                 }
  333.             }
  334.         }
  335.     }
  336.     Table()
  337.     {
  338.     }
  339. };
  340.  
  341. int main()
  342. {
  343.     char filePath[BUFFER_SIZE];
  344.     std::cin >> filePath;
  345.     Table t(filePath);
  346.     t.print();
  347.     // cout << "\n";
  348.     // Cell cells[5] = {{"baba", true}, {"dedo", false}, {"Az", true}, {"zashto tochno az", true}, {"1232432", false}};
  349.     // Row r(cells, 5);
  350.     // t.add(5, r);
  351.     // t.print();
  352.     //  cout << "\n";
  353.     //  t.remove(1);
  354.     //  t.print();
  355. }
  356.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement