I'm a beginner in c++ and I'm training on exercises.
I'm stuck on one part. I would like to insert the string "CH" in front of each vowel in a sentence.
I first tried using string::replace, but it was not the best idea.
I would like to use string::insert to do this.
However, I can't seem to use it properly in a loop to tell it that the [i] is the desired position
Do you have any advice for me?
string message = "you have a secret message to decrypt";
string newMessage = "";
string InsertMessage = "CH";
for (int i = 0; i < message.length(); i++) {
if (
message[i] == 'a' ||
message[i] == 'e' ||
message[i] == 'i' ||
message[i] == 'o' ||
message[i] == 'u' ||
message[i] == 'y')
{
//newMessage = message.replace(i, 1, InsertMessage);
newMessage = message.insert(i, InsertMessage);
}
}
cout << newMessage << endl;
return 0;
This statement
newMessage = message.insert(i, InsertMessage);
does not make a sense at least because it changes the original string message.
I can suggest the following approach shown in the demonstration program below.
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
int main()
{
std::string message = "you have a secret message to decrypt";
std::string newMessage;
std::string InsertMessage = "CH";
const char *vowels = "aeiouy";
auto n = std::count_if( std::begin( message ), std::end( message ),
[vowels]( const auto &c ) { return std::strchr( vowels, c ); } );
newMessage.resize( message.size() + n * InsertMessage.size() );
std::string::size_type pos = 0;
do
{
auto i = message.find_first_of( vowels, pos );
if (i == std::string::npos)
{
newMessage += message.substr( pos );
pos = i;
}
else
{
newMessage += message.substr( pos, i - pos );
newMessage += InsertMessage;
pos = i;
newMessage += message[pos++];
}
} while( pos != std::string::npos );
std::cout << newMessage << '\n';
}
The program output is
CHyCHoCHu hCHavCHe CHa sCHecrCHet mCHessCHagCHe tCHo dCHecrCHypt
Thanks for your answers, I'll work on it :)
Related
C++ question:
I have the query in txt like this:
CUSTOMER_ID=4155&ORDER_ITEM_TYPE_ID=1&ORDER_ITEM_TYPE_NAME=Product&ORDER_ITEM_SKU=&ORDER_CURRENCY_CODE=UAH
How can I get these fields to make it look nearly like:
Customer_ID: 4155
ORDER_ITEM_TYPE_ID: 1
// and etc...
I know there is a separator "&" between each field, but I don't know how to do it properly.
Use methods of std::string like find,substr. Example:
const std::string field = "CUSTOMER_ID=4155&ORDER_ITEM_TYPE_ID=1&ORDER_ITEM_TYPE_NAME=Product&ORDER_ITEM_SKU=&ORDER_CURRENCY_CODE=UAH";
const char separator = '&';
const char equal = '=';
std::string::size_type cur = 0;
while ( cur != std::string::npos )
{
std::string name;
std::string value;
std::string::size_type newPos = field.find(equal, cur);
if ( newPos != std::string::npos )
{
name = field.substr( cur, newPos - cur );
cur = newPos + 1;
newPos = field.find(separator, cur);
value = field.substr( cur, ( newPos == std::string::npos ) ? std::string::npos : newPos - cur );
cur = ( newPos == std::string::npos ) ? std::string::npos : newPos + 1;
std::cout << name << ": " << value << std::endl;
}
else
{
break;
}
}
try
`char str[10][20];
int len = 0;
int count = 0;
while((c = string[i])!= EOC )
/* EOC : End of Character */
{
if (c == '&') {
str[count][len] = '\0';
len = 0;
count++;
continue;
}
str[count][len] = c;
len++;
}
Replace all '&' with replace and then when you write the data after this back into a file it's formated as requested.
std::ifstream infile("thefile.txt");
while (std::getline(infile, line)) //Read File line by line
{
std::replace( line.begin(), line.end(), '&', '\0'); // replace all '&' to '\0'
cout << line << endl;
}
i want a program which reverse given string in the below format.
Suppose if I input string as = "This is a boy"
then i want output reverse sting as = "boya si ishT"
one more example
Input string = "if a"
Output String = "af i"
please help.
i have written below program but not working as expected.
char string[] = "This is a boy\0";
char reverse[100] = {0};
int start = 0;
int len = strlen(string)-1;
int space= 0;
bool flag = false;
int count = 0;
while(len >= 0)
{
if(string[len] == ' ' )
{
len--;
flag = true;
}
if(flag && (string[len-1]) == ' ')
{
reverse[start] = string[len];
reverse[++start] = ' ' ;
len--;
start++;
flag = false;
continue;
}
reverse[start] = string[len];
flag = false;
start++;
len--;
}
Since you have the C++ tag
#include <string>
#include <algorithm>
#include <iostream>
std::string str = "This is a boy";
std::reverse(str.begin(), str.end());
std::cout << str;
or
char str[] = "This is a boy";
std::reverse(str, str + strlen(str));
I'm building this webcrawler here. This error occurs to me when I start debugging and sends me to memcpy.asm or xstring or dbgdel.cpp files showing me different lines of these files every time.
I was wondering if the code is wrong somehow. I started thinking I am accessing memory blocks that I shouldn't. Here is some code. I hope you can help.
The idea is to iterate through httpContent and get all the URLs from the <a> tags. I am looking for href=" in the beginning and then for the next ". What is in between I am trying to put in temp, then pass the content of temp to an array of strings.
struct Url
{
string host;
string path;
};
int main(){
struct Url website;
string href[100];
website.host = "crawlertest.cs.tu-varna.bg";
website.path = "";
string httpContent = downloadHTTP(website);
for(unsigned int i = 0; i <= httpContent.length()-7; i++){
char c = httpContent[i];
if(c == 'h'){
c = httpContent[i+1];
if(c == 'r'){
c = httpContent[i+2];
if(c == 'e'){
c = httpContent[i+3];
if(c == 'f'){
c = httpContent[i+4];
if(c == '='){
c = httpContent[i+5];
if(c == '\"'){
i+=6;
c = httpContent[i];
string temp = "";
while(c!='\"'){
i++;
c = httpContent[i];
temp+= c;
}
href[i] = temp;
temp = "";
cout<<href[i]<<endl;
}}}}}}
}
system("pause");
return 0;
}
UPDATE
I edited the =, now ==
I am also stopping the iterations 7 positions earlier so the 'if's should not be problem.
I am getting the same errors though.
Use std::vector< std::string > href; to store your result.
With string::find you can find sequence in strings and with string::substr you can extract them from string.
#include <vetor>
#include <string>
struct Url
{
string host;
string path;
};
int main(){
struct Url website;
website.host = "crawlertest.cs.tu-varna.bg";
website.path = "";
std::string httpContent = downloadHTTP(website);
std::vector< std::string > href;
std::size_t pos = httpContent.find("href="); // serach for first "href="
while ( pos != string::npos )
{
pos = httpContent.find( '"', pos+5 ); // serch for '"' at start
if ( pos != string::npos )
{
std::size_t posSt = pos + 1;
pos = httpContent.find( '"', posSt ); // search for '"' at end
if ( pos != string::npos )
{
href.push_back( httpContent.substr( posSt, pos - posSt ) ); // extract ref and append to result
pos = httpContent.find( "href=", pos+1 ); // search for next "href="
}
}
}
system("pause");
return 0;
}
I was trying to create a program to calculate the simplified version of a polynomial expression. I want to separate all of the variables, and constants (with plus signs) but my program seems to not be recognizing some of the plus signs in my string:
string al("2x+2+6y+8^7");
vector<string> variableStorage;
for (auto &c : al)
{
static int count = 0;
static int lastcount = 0;
if(c == '+' || count == al.length()-1)
{
static int spot(0);
variableStorage.push_back(al.substr(lastcount, count));
lastcount = count+1;
++spot;
}
++count;
}
for(auto c : variableStorage)
cout << c << endl;
When I run this program, I get the following output:
2x
2+6y
6y+8^7
8^7
But my desired output is:
2x
2
6y
8^7
I tried checking my math for any mistakes, but it seems good as far as I can see.
Split the string (tokenize) at the +s
#include <string>
#include <vector>
using namespace std;
// This code from another SO question about splitting strings in C++
// http://stackoverflow.com/questions/236129/how-to-split-a-string-in-c
template < class ContainerT >
void tokenize(const std::string& str, ContainerT& tokens,
const std::string& delimiters = " ", bool trimEmpty = false)
{
std::string::size_type pos, lastPos = 0;
while(true)
{
pos = str.find_first_of(delimiters, lastPos);
if(pos == std::string::npos)
{
pos = str.length();
if(pos != lastPos || !trimEmpty)
tokens.push_back(ContainerT::value_type(str.data()+lastPos,
(ContainerT::value_type::size_type)pos-lastPos ));
break;
}
else
{
if(pos != lastPos || !trimEmpty)
tokens.push_back(ContainerT::value_type(str.data()+lastPos,
(ContainerT::value_type::size_type)pos-lastPos ));
}
lastPos = pos + 1;
}
};
int main( void )
{
string al("2x+2+6y+8^7");
vector<string> variableStorage;
tokenize( al, viariableStorage );
for(auto c : variableStorage)
cout << c << endl;
//Your items are in variableStorage at this point
return( 0 );
}
The code above is not tested, it's late and I'm feeling lazy. I hope it gets the concept across.
substr takes starting position and length. So you should be calling al.substr(lastcount, count-lastcount)
I am writing a program for school that is supposed to check the strength of passwords and separate them into 3 parameters. I am having an issue identifying special characters in a strong to classify a strong character. any help is greatly appreciated.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string input;
bool complete = false;
bool hasUpper = false;
bool hasLower = false;
bool hasDigit = false;
bool specialChar = false;
int count;
char special = 'a';
do
{
cout << endl << "Enter a password to rate its strength. Enter q to quit." << endl;
cin >> input;
for(count =0; count < input.size(); count++)
{
if( islower(input[count]) )
hasLower = true;
if( isupper(input[count]) )
hasUpper = true;
if( isdigit(input[count]) )
hasDigit = true;
special = input.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 ");
if (special != 'a')
specialChar = true;
}
if (hasLower && hasUpper && hasDigit && specialChar && (count >= 8))
{
cout << "Strong" << endl;
}
else if((hasLower || hasUpper) && hasDigit && (count >= 6))
{
cout << "Moderate" << endl;
}
else
{
cout << "Weak" << endl;
}
if (input == "q") complete = true;
}while (!complete);
return 0;
}
size_t special;
if (special != string::npos)
specialChar = true;
find_first_not_of returns the index of the found character, or the special value string::npos if no character is found.
Because find_first_not_of returns an index not a character, you must declare special as size_t not char.
This is more a comment on your code structure, than a direct
answer to your immediate question. (If you correct the
structure, the problem will disappear, however.) At present,
you seem to be mixing two different solutions, in a very odd
way. In particular, you're calling input.find_first_not_of
each time through the loop, despite the fact that it checks all
of the characters. You should choose one solution, and use it
for all of the conditions.
If you want to loop, checking each characters:
for ( int count = 0; count != input.size(); ++ count ) {
unsigned char ch = input[count]; // To avoid undefined behavior
if ( islower( ch ) {
hasLower = true;
} else if ( isupper( ch ) ) {
hasUpper = true;
} else if ( isdigit( ch ) ) {
hasDigit = true;
} else {
hasSpecial = true;
}
}
Note that the use of if/else if means that you don't need
a test for special—special is anything that doesn't meet any
of the preceding tests. If you wanted a test, !isalnum( ch )
would serve the purpose just fine.
Alternatively, you can use standard functions for each:
hasLower = std::find_if(
input.begin(),
input.end(),
[]( unsigned char ch ) { return islower( ch ); } )
!= input.end();
hasUpper = std::find_if(
input.begin(),
input.end(),
[]( unsigned char ch ) { return isupper( ch ); } )
!= input.end();
hasDigit = std::find_if(
input.begin(),
input.end(),
[]( unsigned char ch ) { return isdigit( ch ); } )
!= input.end();
hasSpecial = std::find_if(
input.begin(),
input.end(),
[]( unsigned char ch ) { return !isalnum( ch ); } )
!= input.end();
The lambda functions in the above is only available in C++11.
If you do not have C++11, you would have to write a separate
functional object for each, which would make this solution far
heavier than the simple loop above. Unless, of course, you're
doing a lot of text processing, in which case, the functional
objects would go in your tool kit, to be reused many times.
Unless you have the functional objects ready and in your tool
kit, however, this seems more complex than the simple loop, even
with lambda. (On the other hand, it's more idiomatic. But
then, it's hard to imagine any experienced C++ programmer
without the functional objects in his toolkit.)