#include <cassert> #include <cstring> #include <cstdlib> #include <cstdio> #include <cstdint> #include <iostream> using namespace std; class CFile { public: CFile(void); // copy cons, dtor, op= CFile(const CFile &src); CFile & operator = (const CFile &src); ~CFile (void); uint32_t write ( const uint8_t *src, uint32_t bytes ); uint32_t read ( uint8_t * dst, uint32_t bytes ); bool seek ( uint32_t offset ); void truncate ( void ); uint32_t fileSize ( void ) const; void addVersion ( void ); bool undoVersion ( void ); void copyWithoudLinkedList( CFile &src ); uint8_t *m_Data; uint32_t m_Len; uint32_t m_Position; uint32_t m_Capacity; size_t m_LenHistory; CFile *m_History; }; CFile::CFile(void) :m_Data(nullptr), m_Len(0), m_Position(0), m_Capacity(0),m_LenHistory(0), m_History(nullptr) { } CFile::~CFile (void) { delete[] m_Data; //Delete linked list if (m_History) delete m_History; } CFile* copyLinkedList(CFile *list) { if(list == nullptr) return nullptr; CFile* result = new CFile; result->m_Capacity = list->m_Capacity; result->m_Len = list->m_Len; result->m_Position = list->m_Position; result->m_LenHistory = list->m_LenHistory; result->m_Data = new uint8_t[list->m_Capacity]; memcpy(result->m_Data, list->m_Data, result->m_Len); result->m_History = copyLinkedList(list->m_History); return result; } // Kopírující konstruktor CFile::CFile(const CFile &src) : m_Data(new uint8_t[src.m_Capacity]), m_Len(src.m_Len), m_Position(src.m_Position), m_Capacity(src.m_Capacity), m_LenHistory(src.m_LenHistory) { memcpy(m_Data, src.m_Data, m_Len); m_History = copyLinkedList(src.m_History); } void CFile::copyWithoudLinkedList( CFile &src ) { m_Capacity = src.m_Capacity; m_Len = src.m_Len; m_LenHistory = src.m_LenHistory; m_Position = src.m_Position; m_Data = new uint8_t[src.m_Capacity]; memcpy(m_Data, src.m_Data, m_Len); } uint32_t CFile::fileSize ( void ) const { return m_Len; } void CFile::truncate ( void ) { m_Len = m_Position; } bool CFile::seek ( uint32_t offset ) { if(offset>=0 && offset <=m_Len) { m_Position = offset; return true; } return false; } uint32_t CFile::write ( const uint8_t *src, uint32_t bytes ) { int lastLen = m_Len; if( bytes + m_Len +1 > m_Capacity ) { while( m_Len + bytes + 1 > m_Capacity ) m_Capacity += m_Capacity/2 +10; uint8_t *tmp = new uint8_t [m_Capacity]; memcpy(tmp, m_Data, m_Len); memcpy(tmp + m_Position, src, bytes); delete [] m_Data; m_Data = tmp; } else memcpy(m_Data+m_Position, src, bytes); m_Position += bytes; int k = (m_Position-lastLen); if(k>0) m_Len += k; // počet zapsaných bajtů return bytes; } uint32_t CFile::read( uint8_t * dst, uint32_t bytes ) { if(m_Position+bytes <= m_Len) { memcpy(dst, m_Data+m_Position, bytes); m_Position += bytes; return bytes; } bytes = (m_Len-m_Position); memcpy(dst, m_Data+m_Position, bytes); m_Position += bytes; return bytes; } CFile & CFile::operator = (const CFile &src) { // Pokud to co mám zkopírovat je rovno danému objektu if(this == &src) return *this; delete [] m_Data; m_Data = new uint8_t[src.m_Capacity]; m_Len = src.m_Len; m_Capacity = src.m_Capacity; m_Position = src.m_Position; m_LenHistory = src.m_LenHistory; memcpy(m_Data, src.m_Data, m_Len); m_History = copyLinkedList(src.m_History); return *this; } bool writeTest ( CFile & x, const initializer_list<uint8_t> & data, uint32_t wrLen ) { return x . write ( data . begin (), data . size () ) == wrLen; } bool readTest ( CFile &x, const initializer_list<uint8_t> & data, uint32_t rdLen ) { uint8_t tmp[100]; uint32_t idx = 0; if ( x . read ( tmp, rdLen ) != data . size ()) return false; for ( auto v : data ) if ( tmp[idx++] != v ) return false; return true; } void CFile::addVersion ( void ) { CFile *tmp = m_History; CFile *prev; if(!tmp) { tmp = new CFile(); tmp->copyWithoudLinkedList(*this); this->m_History = tmp; this->m_History->m_History = nullptr; m_LenHistory++; } else { while(tmp) { prev = tmp; tmp = tmp->m_History; } tmp = new CFile(); tmp->copyWithoudLinkedList(*this); prev->m_History = tmp; prev->m_History->m_History = nullptr; m_LenHistory++; } } bool CFile::undoVersion ( void ) { if(m_LenHistory == 0) return false; CFile *tmp = m_History; CFile *prev; while(tmp) { prev = tmp; tmp = tmp->m_History; } delete [] m_Data; m_Data = new uint8_t[prev->m_Capacity]; m_Len = prev->m_Len; m_Capacity = prev->m_Capacity; m_Position = prev->m_Position; m_LenHistory = prev->m_LenHistory; memcpy(m_Data, prev->m_Data, m_Len); // Delete last element from linked list CFile *tmp2 = m_History; CFile *prev2; while(tmp2 != prev) { prev2 = tmp2; tmp2 = tmp2->m_History; } delete tmp2; prev2->m_History = nullptr; return true; } int main (void) { CFile f0; assert ( writeTest ( f0, { 10, 20, 30 }, 3 ) ); assert ( f0 . fileSize () == 3 ); assert ( writeTest ( f0, { 60, 70, 80 }, 3 ) ); assert ( f0 . fileSize () == 6 ); assert ( f0 . seek ( 2 )); assert ( writeTest ( f0, { 5, 4 }, 2 ) ); assert ( f0 . fileSize () == 6 ); assert ( f0 . seek ( 1 )); assert ( readTest ( f0, { 20, 5, 4, 70, 80 }, 7 )); assert ( f0 . seek ( 3 )); f0 . addVersion(); cout <<" number copies f0: " << f0.m_LenHistory << endl << endl; assert ( f0 . seek ( 6 )); assert ( writeTest ( f0, { 100, 101, 102, 103 }, 4 ) ); f0 . addVersion(); cout <<" m_Data f0: " << f0.m_Data << endl << endl; cout <<" m_Data in 1.copy f0: " << f0.m_History->m_Data << endl << endl; cout <<" m_Data in 2.copy f0: " << f0.m_History->m_History->m_Data << endl << endl; cout <<" number copies f0: " << f0.m_LenHistory << endl << endl; assert ( f0 . seek ( 5 )); CFile f1 ( f0 ); cout <<" m_Data f1: " << f1.m_Data << endl << endl; cout <<" m_Data in 1.copy f1: " << f1.m_History->m_Data << endl << endl; cout <<" m_Data in 2.copy f1: " << f1.m_History->m_History->m_Data << endl << endl; cout <<" number copies f1: " << f1.m_LenHistory << endl << endl; f0 . truncate (); assert ( f0 . seek ( 0 )); assert ( readTest ( f0, { 10, 20, 5, 4, 70 }, 20 )); assert ( f0 . undoVersion () ); assert ( f0 . seek ( 0 )); assert ( readTest ( f0, { 10, 20, 5, 4, 70, 80, 100, 101, 102, 103 }, 20 )); assert ( f0 . undoVersion () ); assert ( f0 . seek ( 0 )); assert ( readTest ( f0, { 10, 20, 5, 4, 70, 80 }, 20 )); assert ( !f0 . seek ( 100 )); assert ( writeTest ( f1, { 200, 210, 220 }, 3 ) ); assert ( f1 . seek ( 0 )); assert ( readTest ( f1, { 10, 20, 5, 4, 70, 200, 210, 220, 102, 103 }, 20 )); assert ( f1 . undoVersion () ); assert ( f1 . undoVersion () ); assert ( readTest ( f1, { 4, 70, 80 }, 20 )); assert ( !f1 . undoVersion () ); return 0; }
Write, Run & Share C++ code online using OneCompiler's C++ online compiler for free. It's one of the robust, feature-rich online compilers for C++ language, running on the latest version 17. Getting started with the OneCompiler's C++ compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as C++
and start coding!
OneCompiler's C++ online compiler supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample program which takes name as input and print your name with hello.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name;
cout << "Enter name:";
getline (cin, name);
cout << "Hello " << name;
return 0;
}
C++ is a widely used middle-level programming language.
When ever you want to perform a set of operations based on a condition If-Else is used.
if(conditional-expression) {
//code
}
else {
//code
}
You can also use if-else for nested Ifs and If-Else-If ladder when multiple conditions are to be performed on a single variable.
Switch is an alternative to If-Else-If ladder.
switch(conditional-expression){
case value1:
// code
break; // optional
case value2:
// code
break; // optional
......
default:
code to be executed when all the above cases are not matched;
}
For loop is used to iterate a set of statements based on a condition.
for(Initialization; Condition; Increment/decrement){
//code
}
While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.
while (condition) {
// code
}
Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.
do {
// code
} while (condition);
Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increases re-usuability and modularity. Function gets run only when it is called.
return_type function_name(parameters);
function_name (parameters)
return_type function_name(parameters) {
// code
}