I am writing a program that inputs a string, gets rid of the vowels, and
if two consonants typed right after one another are the same, the output should print only one of those two.
I have been trying but it looks like that only the first double consonant is
printed as one, the rest remain the same.
How come?
j was declared to have the value i+1, so it had the value 1. j's value was never changed from that so it remained to be 1.
so you have to update j in the for-loop, also you must use str[j] instead of str[i] (in the looping condition) to make sure you will not access a memory out of reach.
1 2 3 4 5 6 7
for (int i = 0; str[i - 1] != '\0'; i++, j = i + 1)
{
if (str[i] == str[j])
{
str[j] = ' ';
}
}
Grime has already noted how you can fix your program, but you should also probably make sure that the headers you are including are actually required. Almost all of them are not.
Anyway, just for fun I got curious about writing the code in a slightly different way, and the result is below (you can run it by clicking on the little wheel, top right of code box). As you can see, you really don't need most of the headers you had included (albeit the program is a little different to your own).
Hi, thanks for your hints.
I continued the code to make sure that the consonant output
would be taken by the first 3 characters and the last 2.
My code seems to run very smoothly, but after a few trials,
it stops working and a window appears saying: "debug assession failed"
so I have to click "abort" to start again.
Not sure why is doing that.
Hi, thanks for your hints.
I continued the code to make sure that the consonant output
would be taken by the first 3 characters and the last 2.
My code seems to run very smoothly, but after a few trials,
it stops working and a window appears saying: "debug assession failed"
so I have to click "abort" to start again.
Not sure why is doing that.
I also wanted to ask? Would it actually be a big deal to include libraries that are not used?
What does that imply?
As I had said after you posted it the first time,
change for (int i = 0; str[j] != '\0'; i++, j = i + 1
to for (int i = 0; str[i - 1] != '\0'; i++, j = i + 1
That's what's causing the assertion.
Also str.erase(remove_if(str.begin(), str.end(), isspace), str.end());
should be just remove_if(str.begin(), str.end(), isspace);
remove_if takes care of the "removing" part (it's in the name man..), you wrote this on another thread too (sorry if it isn't you).
Nothing wrong with including extra headers, it's just that it's going to take you longer to compile, nothing else. But in my opinion it's better you have a habit of including only the headers you need, even if you're just playing around and testing.
Also .h headers are C headers.
1 2
#include <stdlib.h>
#include <ctype.h>
Use the C++ counterparts (add c at the beginning and remove the .h)
lastchance I know that std::string don't rely on '\0' but instead their size.
However that being said, I have noticed that identifier_of_string[size] seems to be a '\0'. Might be a coincidence.
#include <iostream>
#include <string>
int main()
{
char answer ;
do
{
std::string str ;
std::cout << "enter a string: " ;
std::getline( std::cin, str ) ;
if( str.empty() ) return 0 ; // empty string, nothing to be done
// if two consonants typed right after one another are the same,
// get rid of the second one
// we need to do this before removing the vowels.
// eg. if the string is "tata", he two consonants are not typed right after one another
// note that this will also remove duplicate vowels; but we are required to remove all vowels anyway
{
std::string str_no_dup ;
str_no_dup += str[0] ; // the first character is not a repeating character
// the first character has no previous character
// so we start this loop from the second character (position 1)
for( std::size_t i = 1 ; i < str.size() ; ++i )
{
if( str[i] != str[i-1] ) // if it is not a repeating character
str_no_dup += str[i] ; // append it to str_no_dup
}
str = str_no_dup ; // str with duplicates removed
}
// get rid of all the vowels now
{
const std::string vowels = "aeiouAEIOU" ;
std::string str_no_vowels ;
for( std::size_t i = 0 ; i < str.size() ; ++i )
{
constchar c = str[i] ;
if( vowels.find(c) == std::string::npos ) // if the character is not a vowel
str_no_vowels += c ; // append it to str_no_vowels
}
str = str_no_vowels ; // str with vowels removed
}
std::cout << "endoded string: " << str << '\n' ;
std::cout << "try again (y/n)? " ;
std::cin >> answer ;
std::cin.ignore( 1000, '\n' ) ;
}
while( answer == 'Y' || answer == 'y' ) ;
}
for (int i = 0; str[i - 1] != '\0'; i++, j = i + 1) That produces undefined behavior the very first time through the loop because it tests str[-1].
I have noticed that identifier_of_string[size] seems to be a '\0'.
This type of thinking is a common source of bugs. Don't rely on things that seem to work because they might work that way purely by accident. Look it up and determine if the behavior is supported or not.
In the case of str[str.size()], one of the more recent standards requires that std::string's be null terminated, but if you're using an earlier compiler, it isn't true.
Bottom line: always use string::size() to tell where a string ends.