[Dev-C++] Multiple Search and Replace Function
Open Source C & C++ IDE for Windows
Brought to you by:
claplace
|
From: CARLSON, J. M. <CA...@st...> - 2003-06-27 11:48:06
|
For all new programmers, if you follow these programs from me you will see
some examples of how I write code, (good or bad). The initial version of
this program would search for a text and replace it with another text. It
did that but I have a much larger purpose in mind. My end goal is to make a
program (that anyone can use - although I don't know how many would want to)
that will take a file that I want to import into Access 2000 and strip off
all the junk headers and footers that keep the columns from importing
without errors.
The multiple search and replace function is step two in what I believe will
be a 4 step process. Step three will be to open files and read text,
already done, but will post later.
Step 4 will be to combine steps 3 and 2 into a coherent program.
Here is step two.
// Multiple Search and Replace Function
// For use and analysis especially for new programmers
//
// Praise God for His Goodness and Mercy
// 27 June 2003 Jay A Carlson
// Multiple Search and Replace Implementation and Testing
//
// Takes an input text and replacement text and makes it happen
// In the future I will have an input text file and a change file
// to end up with a new converted file.
//
// The search and replace specifications take the form of
// <> <search for this> <replace with this>;
// number of replacements (0 means replace all)
//
// [] [search] [replace]
// 5
//
// <> <myArray[9]> <thisArray[10]>
// 3
//
// ^* ^std::cout<<test[5];* ^printf("test[3]");*
// 0
//
// Notice by being able to specify the start and stop delimiters for each
// search and replace you don't have to worry about nesting problems.
//
// abbreviations used
// srt -- search and replace text
// arc = actual_replacement_count
// drc = desired_replacement_count
#include <iostream> // for std::cout
#include <string> // for std::string
#include <vector> // guess what - for vectors
// this is a function whose sole purpose in life is to get the word, or
words
// between the delimiters represented by the variables start and stop
// debug -- a way of showing more or less information in a hurry
std::string getword_s(char start, char stop, std::string &srt) {
unsigned int first = srt.find_first_of(start) + 1;
unsigned int last = srt.find_first_of(stop) - 1;
unsigned int len = last - first + 1; // length of word(s) between
delimiters
// get the substring of srt, starting at position first (delimeter +1)
and
// go for len charachers. If len is larger than the string srt it
will
// just stop at the end.
std::string word = srt.substr(first, len);
// now that we got the word(s) we wanted out between the delimiters, it
is
// time to remove that section so that we can work with the next part, if
// any.
srt = srt.substr(last + 2, srt.length());
return word;
}
// the name says it all
void search_and_replace(std::string &text, std::string &srt,
unsigned int drc, const bool debug) {
// I didn't want accidental spaces to cause the program to glitch
// so in the next few lines I remove all spaces before delimiters.
// This also simplfied getting the delimiters
unsigned int eatwhite = srt.find_first_not_of(' ');
srt = srt.substr(eatwhite,srt.length());
char start = srt[0]; // the starting delimiter is now the first char in
srt
srt = srt.substr(1,srt.length());
eatwhite = srt.find_first_not_of(' ');
srt = srt.substr(eatwhite,srt.length());
char stop = srt[0]; // the ending delimiter is now the first char in
srt
if (debug) {
std::cout << "\nStart Delimiter = " << start;
std::cout << "\nStop Delimiter = " << stop;
}
// remove the delimiter specifiers so we can look for the search
// and replace words
srt = srt.substr(2, srt.length()-1);
// get the word(s) for the search part
std::string search = getword_s(start, stop, srt);
if (debug) std::cout << "\n";
// get the word(s) for the replace part
std::string replace = getword_s(start, stop, srt);
if (debug) {
std::cout << "\nThe word(s) to search for is/are : \"" << search <<
"\"";
std::cout << "\nThe word(s) to replace with is/are: \"" << replace <<
"\"";
std::cout << "\n";
}
// pos and new_pos are needed to prevent recursive replacements of
text
// resulting in a "loop until crash condition"
unsigned int pos = 0;
unsigned int new_pos = 0;
unsigned int arc = 0;
// Part one of while (before the "and")
// Need to check to see that what your searching for is there before
// you try to replace it. If it is not there you can't replace it,
and
// your program will terminate before you can view any std::cout
data.
// Part two of while (after the "and")
// While advancing through the text making replacments continue if
// the desired number of replacements hasn't yet been made or
// "replace all" if desired replacement count equals zero.
while (text.length() > text.find(search,pos) and ((arc < drc) or (drc
== 0))) {
// If the search word is not found, it cannot be replaced!!
// mark the place of where the next new position will be
new_pos = text.find(search,pos) + replace.length()-1;
// make the string replacement
text = text.replace(text.find(search,pos), search.length(),
replace);
// go to the new position (after the string replacement) to prevent
// a recursive string replacement (and subsequent crash)
pos = new_pos;
arc++; // advance actual replacement counter.
} // end of while
std::cout << "\nActual Replacement Count = " << arc;
} // end of function
int main(void) {
bool debug = true; // toggle to see more details
std::string original = "I will be 40 40 40 40 40 next year.";
std::string new_text = original;
// Oh yeah - here I am experimenting with vectors of strings
// Vectors are almost like arrays, but better
std::vector<std::string>srt(6); // srt - search and replace text
std::vector<unsigned int>drc(6);
// Test no match condition
srt[0] = " < > <35> <34>";
drc[0] = 4;
// Test replace with same size
srt[1] = " ( ) (40) (38)";
drc[1] = 3;
// Test replace with smaller size
srt[2] = "[ ] [ 38] []";
drc[2] = 0;
// Test replace with a bigger text
srt[3] = "[] [next] [a very old man next]";
drc[3] = 3;
// Test replace
srt[4] = "[] [40] []";
drc[4] = 2;
// Test replace
srt[5] = "[] [ ] [ ]";
drc[5] = 1;
for(int i = 0; i < 6; i++) {
std::cout << "\n\n\n\n\n\n\n\n\n\n\n\n\nSearch and Replace Text = "
<< srt[i];
if (drc[i] == 0) std::cout << "\nDesired Replacement Count = All";
else std::cout << "\nDesired Replacement Count = " << drc[i];
search_and_replace(new_text, srt[i], drc[i], debug);
std::cout << "\nOriginal text: = " << original;
std::cout << "\nNew text: = " << new_text;
std::cout << "\n\n";
system("pause");
original = new_text;
}
return 0;
}
// Praise God for His Goodness and Mercy
// Jay A. Carlson
//
// Constuctive criticism will be appreciated.
|