Replacing four letter words with 'love'

This is homework- I have to use C-strings and in this code I need to replace all four letter words with the word love. My original idea was to perform a check to make sure I have 4 letters together and then change those instances to be 'l', 'o', 'v', 'e' respectively. I encountered a break point in my if statement that checked to make sure I had four letters. Here is what it looks like(also please keep the language simple, I am really new with programming):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
  #include<iostream>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<istream>
using namespace std;

int main()
{
	bool runAgain;
	do
	{
		char userString[101];
		cout << "Please enter a sentence to be modified: " << endl;
		cin.getline(userString, 100);
		for (int i = 0; i < 101; i++)
		{
			if ((userString[i] == isalpha(userString[i])) && (userString[i + 1] == isalpha(userString[i + 1])) && (userString[i + 2] == isalpha(userString[i + 2])) && (userString[i + 3] == isalpha(userString[i + 3])))
			{
				userString[i] = 'l';
				userString[i + 1] = 'o';
				userString[i + 2] = 'v';
				userString[i + 3] = 'e';
			}
		}
		cout << userString<<endl;
		cout << "Would you like to run this again? (1 for yes, 0 for no)" << endl;
		cin >> runAgain;
	} while (runAgain == true);
	system("pause");
	return 0;
}
Last edited on
this does not look correct.

You need logic that seeks the pattern

oLLLLo where o is not a letter, and L is a letter. o can be nothing (start of string, does not exist, or end of string, which is the numerical value zero) or other things like space, punctuation, etc.

once you replace, start looking again at positon o (the second one) in the string.

At a guess (working it by hand here) ... does it happen to replace a 6 letter word with lllove?
I had a break point in the if statement so it wouldn't even compile.
I changed my if statements to reflect that check process by doing this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
for (int i = 0; i < 101; i++)
		{
			if (userString[i] != isalpha(userString[i]))
			{
				if (userString[i + 1] == isalpha(userString[i + 1]))
				{
					if (userString[i + 1] == isupper(userString[i + i]))
					{
						if (userString[i + 2] == isalpha(userString[i + 2]))
						{
							if (userString[i + 3] == isalpha(userString[i + 3]))
							{
								if (userString[i + 4] == isalpha(userString[i + 4]))
								{
									if (userString[i + 5] != isalpha(userString[i + 5]))
									{
										userString[i + 1] = 'L';
										userString[i + 2] = 'o';
										userString[i + 3] = 'v';
										userString[i + 4] = 'e';
									}
								}
							}
						}
					}
				}
			}
		}


Now its giving me an error that says it "cannot open" my program "for writing"
You are using isalpha wrong; It returns a bool, not a char.

1
2
3
4
if(isalpha(userString[i+1]) == true)
{
// it is an alphabetical character.
}




Instead of the getline function for cin, I'd suggest the >> operator, this will get one word at a time so you don't have to worry about checking before and after for white-space.
1
2
3
4
while(cin >> userWord)
{
    // do your checking here.
}


You could then use strlen from <cstring> to tell you if the word is 4 letters, but you'd still have to check that it didn't have numbers in it....
Last edited on
I think my professor wants us to use the getline function. I changed that too, but I still have a break when I try to enter my for loop. Here is the updated code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<istream>
using namespace std;

int main()
{
	bool runAgain;
	do
	{
		char userString[101];
		cout << "Please enter a sentence to be modified: " << endl;
		cin.getline(userString, 100);
		for (int i = 0; i < 101; i++)
		{
			if (isspace(userString[i]))
			{
				if (isalpha(userString[i+1]))
				{
						if (isalpha(userString[i + 2]))
						{
							if (isalpha(userString[i + 3]))
							{
								if (isalpha(userString[i + 4]))
								{
									if (isspace(userString[i + 5]))
									{
										userString[i + 1] = 'L';
										userString[i + 2] = 'o';
										userString[i + 3] = 'v';
										userString[i + 4] = 'e';
									}
								}
							}
						}
					}
				}
			}
		cout << userString << endl;
		cout << "Would you like to run this again? (1 for yes, 0 for no)" << endl;
		cin >> runAgain;
	} while (runAgain == true);
	system("pause");
	return 0;
}


It says that I have an assertion failure but I don't know what that means.
Last edited on
iterate until you find zero as a character in the string. That is the end of string marker in C.

you also iterate too far, you cant check array[102] which happens when I = 100... its out of bounds.

char userString[101]; //this is accessible from 0 to 100
cout << "Please enter a sentence to be modified: " << endl;
cin.getline(userString, 100);
for (int i = 0; i < 101; i++) //this is ok but...
//down here you access [I+5]. that is not ok at 99.. etc

so how can I fix that then? Because I can't use strlen because the sentence might be multiple words long.
Because I can't use strlen because the sentence might be multiple words long.

The use of strlen isn't required, but it would certainly simplify the logic inside the loop. What makes you think a string with multiple tokens in it makes strlen useless?
Again I'm still pretty new into programming. I thought that strlen just returned the int value of the length of the string in total. I don't know how to use it to find only four letter sections. But I guess if I don't need strlen, how can I fix this so that I don't get "assertion failure" errors?
one logical error I find in this code
17
18
19
20
21
22
if (isspace(userString[i]))//what if the first word is a 4 letter word?
			{
				if (isalpha(userString[i+1]))
				{
						if (isalpha(userString[i + 2]))
...

that means that if the first word of the sentence is a four letter word the program will fail to notice it

for example

Please enter a sentence to be modified: 
hell doesn't rock rock.
hell doesn't love rock. 


same goes for last word too I guess...
I thought that strlen just returned the int value of the length of the string in total.

It does. That is quite useful when you don't want to exceed the length of the string in total as you do not want to do.

I don't know how to use it to find only four letter sections.

Again, that isn't what you would use it for. You would use it for its intended purpose - to find the length of a C-string.

1
2
3
4
5
6
7
8
9
10
11
12
13
    char userString[101]; //this is accessible from 0 to 100
    cout << "Please enter a sentence to be modified: " << endl;
    cin.getline(userString, 100);

    unsigned length = strlen(userString);
    unsigned tokenLength = 4;

    // Since it is impossible to find a token of length tokenLength in
    // the last bit of a string that is smaller than that, avoid looking for one there:
    for (unsigned i = 0; i < length - tokenLength; i++) {

        // ...        
   }
Ok I think I'm following, except can I keep the same declaration that I used earlier to change them to "love"?
That definitely took care of the assertion failure, however now I'm kinda lost for how to change those four letters to what I need them to be changed to. Does the new for loop parameter not allow me to use i as an index of userString like I did previously (i.e. userString[i+1] = 'l'; ?
closed account (48T7M4Gy)
Working in the 'opposite' direction might be easier.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<iostream>

using namespace std;

int main(){
    bool runAgain;
    do{
        char userString[100];
        cout << "Please enter a sentence to be modified: " << endl;
        cin.getline(userString, 100);
        
        int count = 0;
        for (int i = 0; i < 100; i++){
            if ( isalpha(userString[i]) ){count++;}
            else
            {
                if(count != 4){count = 0;}
                
                if (count == 4){
                    userString[i-4] = 'l';
                    userString[i-3] = 'o';
                    userString[i-2] = 'v';
                    userString[i-1] = 'e';
                    
                    count = 0;
                }
            }
        }
        
        cout << userString<<endl;
        cout << "Would you like to run this again? (1 for yes, 0 for no)" << endl;
        cin >> runAgain;
        cin.ignore(1000, '\n');
    }while (runAgain == true);
    
    system("pause");
    return 0;
}
Please enter a sentence to be modified: 
what is this my dear?frie?
love is love my love?love?
Would you like to run this again? (1 for yes, 0 for no)
1
Please enter a sentence to be modified: 
what four>
love love>
Would you like to run this again? (1 for yes, 0 for no)

Please enter a sentence to be modified: 
what four
love love
Would you like to run this again? (1 for yes, 0 for no)
Last edited on
Does the new for loop parameter not allow me to use i as an index of userString like I did previously (i.e. userString[i+1] = 'l'; ?

You're free to use i as an index.

In Kemort's code you should check out the use of count to track the state required (the length of the current token) as an alternative to your nested if statements (but keep in mind Kemort's overall algorithm processes "unused" portions of the buffer which don't need to be touched.)
Last edited on
closed account (48T7M4Gy)
Yep, there's no point checking unused stuff:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int i = 0;
        int count = 0;
        while(userString[i] != '\0'){
            if ( isalpha(userString[i]) ){count++;}
            else
            {
                if(count != 4){count = 0;}
                
                if (count == 4){
                    userString[i-4] = 'l';
                    userString[i-3] = 'o';
                    userString[i-2] = 'v';
                    userString[i-1] = 'e';
                    
                    count = 0;
                }
            }
            i++;
        }
        std::cout << "String length: " << i << " " << userString << '\n';
Last edited on
Topic archived. No new replies allowed.