Reputation: 21
Hey guys there seems to be an error with my code.
My main problem is with the section where I want to change any occurrence of 'p' followed by a 'h'. In my testing it changes it to a 'q' for some reason, when I want it to change to 'f'.
For convenience the method with the problem is the void change(), in the second for loop.
Can someone please help?
#include <iostream>
#include <list>
#include <ctype.h>
#include <fstream>
using namespace std;
void printList(const list<char> &myList);
void fillList(list<char> &myList);
void change(list <char> &myList);
void printList(const list<char> &myList)
{
list<char>::const_iterator itr;
for (itr = myList.begin(); itr != myList.end(); itr++ ) {
cout <<*itr;
}
cout << '\n' << endl;
}
void fillList(list<char> &myList)
{
ifstream file("test.txt");
string print;
while(file >> print){
for (int i = 0; i<print.length(); i++) {
myList.push_back(print[i]);
}
myList.push_back(' ');
}
}
void change(list <char> &myList)
{
list<char>::iterator itr;
//rules are as follows
for (itr = myList.begin(); itr != myList.end(); itr++ ) {
if (*itr == 'w' ){
*itr = 'v';
}
}
for (itr = myList.begin(); itr != myList.end(); itr++ ) {
if((*itr == 'p' && ++*itr == 'h')){// rule incomplete ask!
*itr = 'f';
}
}
}
int main ()
{
list<char> myList;
ifstream file("test.txt");
const string print;
fillList(myList);
printList(myList);
change(myList);
printList(myList);
return 0;
}
Upvotes: 1
Views: 1336
Reputation: 374
It's because you were incrementing the pointers character and not the iterator. You could fix this by doing *++itr
instead of ++*itr
I've changed your code up, you can easily make new rules.
//we copy the string because we want to modify it without modifying the original
// http://stackoverflow.com/a/14679003/4376737
std::string find_and_replace(string str, const string& find, const string& replace)
{
size_t pos = 0;
while ((pos = str.find(find, pos)) != string::npos) {
str.replace(pos, find.length(), replace);
pos += replace.length();
}
return std::move(str);
}
void change(list <char> &myList)
{
list<char> newlist;
std::stringstream ss;
for (auto&& it = myList.begin(); it != myList.end(); ++it) {
if (*it != ' ') {
ss << *it;
} else {
auto&& newstr = find_and_replace(ss.str(), "ph", "f");
newstr = find_and_replace(newstr, "w", "v");
for (auto&& ch : newstr) {
newlist.push_back(ch);
}
newlist.push_back(' ');
std::stringstream().swap(ss); //this clears the stringstream
}
}
myList = newlist;
}
Output:
hamper moshpit phile wwwphwwwf
hamper moshpit file vvvfvvvf
Upvotes: 1
Reputation: 3950
The code if((*itr == 'p' && ++*itr == 'h'))
does the following:
itr
is p
itr
and increment it
p + 1 = q
what you need to do is increase the iterator, not the value
if(*itr == 'p') {
if(itr == myList.end()) break; // return or do something else
std::list<char>::iterator itr2 = itr;
if(*(++itr2) == 'h') {
// do what you need to
}
}
Edit: Fixed issue with random iterator and check if p
is last char as pointed out in the comments.
Upvotes: 1