#include<iostream>
#define mm 100000000
using namespace std;
void getcontent(char*&c,FILE*f,int &size)
{
if (!c) {
fseek(f, 0, SEEK_END);
size = ftell(f);
if (size > mm || size < 0) { cout << "too big!"; exit(0); }
if (size) {
c = new char[size];
fseek(f, 0, SEEK_SET);
fread(c, 1, size, f);
}
}
}
void del(char* &c, FILE* f, int size,bool r)
{
cout << "object:";
string object,replace; cin >> object; int l = object.size(),h;
if (r) { cout << "replace:"; cin >> replace; h = replace.size(); }
int* next = new int[l];
int k = -1;
next[0] = -1;
for (int i = 1; i < l; i++) {
while (k != -1 && object[k + 1] != object[i]) { k = next[k]; }
if (object[k + 1] == object[i]) { k++; }
next[i] = k;
}
k = 0; int x = 0;
fseek(f, 0, SEEK_SET);
for (int i = 0,j=0; i < size;j=i)
{
for (; j < size &&j-i<l&&c[j] == object[j - i]; j++);
if (j - i == l) { fwrite(c + k, 1, i - k, f); if (r) { fwrite(replace.c_str(), 1, h, f); } i = k = j; x++; }
else if (i == j) { i++; }
else if (next[j - i-1] < 0) { i = j; }
else { i += next[j- i-1]; }
}
delete[]next;
fwrite(c + k, 1, size - k, f);
delete[]c; c = nullptr;
cout <<"done ("<<x<<")\n";
}
int main()
{
FILE* f = nullptr;
string path;
while (!f){
system("CLS");
cout << "txt:";
cin >> path; path = path + ".txt";
f = fopen(path.c_str(), "rb");
}
string command; char* content = nullptr; int size;
while(1)
{
getcontent(content, f, size);
cout <<path<< ".command:";
cin >> command;
if (command == "exit") { delete[]content; fclose(f); return 0; }
else if (command == "cls") { system("cls"); }
else if(size==0){ cout << "empty\n"; }
else if (command == "delete"||command=="replace")
{
delete[]content; content = nullptr;
getcontent(content, f, size);
fclose(f);
f = fopen(path.c_str(), "wb+");
if(command[0]=='d'){ del(content, f, size,false); }
else{ del(content, f, size,true); }
}
else if (command == "read") {
getcontent(content, f, size);
for (int i = 0; i < size; i++) {
printf("%c", content[i]);
}
cout << endl;
}
}
}