Skip to content

Instantly share code, notes, and snippets.

@bathtime
Created March 14, 2018 14:12
Show Gist options
  • Save bathtime/7a88bac9487a95f9be9e43de781dd0fb to your computer and use it in GitHub Desktop.
Save bathtime/7a88bac9487a95f9be9e43de781dd0fb to your computer and use it in GitHub Desktop.
A search and replace function for use with other C++ programs.
//
// Compile with:
// $ g++ -O3 -Wall searchreplace.cpp -o searchreplace
//
// Run with:
// $ searchAndReplace
//
//
// This program searches for user specified text strings (a starting point
// point to an ending point) and replaces them and all contents between
// with text new text.
//
// Example:
//
// Text: "Some great words cannot defeat a great program!"
// Begin: "cannot"
// End: "great"
// Replace: "in a decent"
// Result: "Some great words in a decent program!"
//
// Regex equivalent: /cannot[^great]*great/
//
// If the user enters the beginning searched text as "", then the program
// replaces from the beginning of the string to the first instance of text;
// likewise, if the user enters "" for the end point, the text will be
// replaced from the first instance of the starting word, to the end. The
// user may change this functionality to have just the one word itself be
// replaced by un/commenting the appropriate code.
//
// Due to input/output checking, this program should never run into an
// infinit loop. The bool return lets other functions know if the text was
// or could have been changed.
//
#include<iostream>
#include<string>
#include<ctime>
#include<cstring>
using namespace std;
bool findAndReplaceAllBetween(string &trueText, const std::string &strBegin, const std::string &strEnd, const std::string &strReplace)
{
std::size_t beginFound;
std::size_t endFound;
if (strEnd.empty())
{
if (strBegin.empty())
{
trueText = strReplace;
return true; // Shows that a change has or could be made
}
// Option #1: Replace just the one word
do {
beginFound = trueText.find(strBegin);
// Check for the first part
if (beginFound != std::string::npos)
{
// #1 - Replace just the one word (strBegin):
if (trueText == (trueText.replace(beginFound, strBegin.length(), strReplace)))
continue;
else
return true; // Don't break, it's slower. Just return straight away!
}
return false;
} while (true);
// Option #2: Replace from strBegin to end of text
//trueText.replace(beginFound, trueText.length() - beginFound, strReplace);
//return false;
} else if (strBegin.empty()) {
endFound = trueText.find(strEnd);
if (endFound != std::string::npos)
{
trueText.replace (0, endFound + strEnd.length(), strReplace);
return true;
}
}
do {
beginFound = trueText.find(strBegin);
// Check for the first part
if (beginFound != std::string::npos)
{
endFound = trueText.substr(beginFound + strBegin.length()).find(strEnd);
// Can we find the second part?
if (endFound != std::string::npos)
{
if (trueText == trueText.replace(beginFound, strEnd.length() + endFound + strBegin.length(), strReplace))
continue;
else
return true;
}
}
// If we made it here, nothing was found.
return false;
} while(true);
// If you made it here, something went seriously wrong; the 'return false' just above should alway catch first.
return false;
}
int main ()
{
const std::string sText = "Some great words cannot defeat a great program!";
const std::string sBegin = "";
const std::string sEnd = "words";
const std::string sReplace = "gestures.";
std::cout << "\n" << "Phrase:\n\n" << sText << "\n\nFrom \"" << sBegin << "\"\nTo \"" << sEnd << "\"\nWith \"" << sReplace << "\"\n\n\n";
std::string sTextCopy;
// Let the benchmark be the judge.
std::clock_t start;
double duration;
start = std::clock();
// What? You don't replace text this much? Fiddlesticks!
for (int i = 0; i < 1000; i++)
{
// Refresh modified text with fresh new copy each time
sTextCopy = sText;
findAndReplaceAllBetween(sTextCopy, sBegin, sEnd, sReplace);
}
// 18.42
// It's done! Stop timer!
duration = ( std::clock() - start ) / (double) CLOCKS_PER_SEC;
std::cout << "Duration: " << duration << "s\n\n";
// Display text result so we know it was done and done correctly
std::cout << sTextCopy << "\n\n\n";
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment