0

so I worked on my program and now I am on a point where I can not find a solution. I need to replace some more signs in the fext file, for now the program only replaces "TIT" with the code number "*245$a", if I want to replace other letters the same way, the program does not change. Does anybody know how I can implement some more replacements in the text file? Let me know if there is a better option to replace more than 5 signs with another ones. Thank you

#include <fstream>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;


int main()
{

    char dateiname[64], kommando[64];

    ifstream iStream;

    cout << "Choose an activity" << endl <<
    " s - search " << endl <<
    " c - convert" << endl <<
    " * - end program" << endl;
    cin.getline(kommando,64,'\n');
    switch(kommando[0])
    {
        case 'c':
            cout << "Enter a text file!" << endl;
            cin.getline(dateiname,64,'\n');
            iStream.open("C://users//silita//desktop//schwarz.txt");

        case 's':
            break;
        case '*':
            return 0;
        default:
            cout << "I can not read " << kommando << endl;
    }

    if (!iStream)
    {
        cout << "The File" << dateiname << "does not exist." << endl;
    }

    string s;
    char o[] = "TIT";
    while (getline(iStream, s))
    {
        while(s.find(o, 0) < s.length())
            s.replace(s.find(o, 0), s.length() - s.find(o, 3),"*245$a");

        cout << s << endl;
    }

    iStream.close();
}
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
silisun
  • 21
  • 1
  • 4
  • duplicate of this http://stackoverflow.com/questions/5343190/how-do-i-replace-all-instances-of-a-string-with-another-string ? – fghj Apr 09 '16 at 03:54
  • this is not a duplicate, because I am already working with a length function, so this can not be the solution. The problem is to replace more than one sign, and that my replace function (at the end of the code) is not correct. The output should be: *245$aAnsätze "korporativer Marktwirtschaft" in der Korea-Krise der frühen fünfziger Jahre / burt my outpout looks like this: *245$a (the text follows in the second row, but should be in the same row) – silisun Apr 10 '16 at 14:07

1 Answers1

1

You can use map in C++ STL to store multiple convert rules:

#include<map>
#include<algorithm>
using namespace std;

map<string,string> convertRules;
typedef map<string,string>::iterator MIT;

void setConvertRules(int numOfRules){
    string word,code;
    for(int i = 0 ; i < numOfRules; ++i){
        cin>>word>>code;

        //Use code as search key in order to decrypt
        //If you want to encrypt, use convertrules[word] = code;
        convertRules[code] = word;
    }
}

To convert a file, just do as follows (some functions and classes need to be declared and implemented first, but here we mainly focus on top-level design):

/* Detailed class implementations are omitted for simplicity */

//a class to store contents of a file
class File;

//a processor to read, insert and overwrite certain file
class FileProcessor;

void FileProcessor::convert(const string &code, const string &word){
    cursor == file.begin();
    while(cursor != fp.end()){
         _fp.convertNextLine(code,word);
    }
}

File file;
FileProcessor filePcr;

int main()

    const string sourceDir = "C://users//silita//desktop//schwarz.txt";
    const string destDir = "C://users//silita//desktop//schwarz_decrypted.txt";

    //Open a .txt file and read in its contents
    if (!file.openAndReadIn(sourceDir)){
        cerr << "The File" << sourceDir << "does not exist." << endl;
        abort();
    }

    //Try to link processor to open file
    if(!fp.linkTo(file)){
        cerr << "Access to file" << sourceDir << "is denied." << endl;
        abort();
    }

    //iterator is like a more safe version of C-style pointer
    //the object type is a string-string pair
    for(MIT it = convertRules.begin(); it != convertRules.end(); ++it){
        fp.convert(it->first, it->second);
    }

    file.saveAs(destDir);
    return 0;
}

Finally, if I would suggest you use C-style strstr function for efficiency when dealing with large files or batch processing. string::find adopts a naive sequential search startegy while strstr is implemented with the famous KMP algorithm for fast pattern match in strings, which is both efficient and thorough(can replace all matchs in one go instead of another for-loop).

Lotayou
  • 162
  • 11
  • Thank you, very helpful idea!! So I am trying to implement the classes now, but I still need some help. What should the two classes (file and filePcr) contain? Would appreciate an answer! – silisun Apr 10 '16 at 14:43
  • @silisun The File class is basically a `vector` where each element of the vector corresponds to a line in your file, it provided `openAndReadIn` and `saveAs` functions, both return a `bool` indicating whether the operation has been successful. The FileProcessor class has a `cursor` of type `vector::iterator` to provide protected access to the contents of the file, while the function 'linkTo' trys to gain such access to file, and will return false in case the target file is classified. The rest the functions can be readily implemented using build-in functions in `std::string`. – Lotayou Apr 11 '16 at 03:23