String replacing deletes latter strings not working - c++

I am trying to replace phrases in a text, but I tried to run this c++ program, but this deletes all the string after the replaced one, so I can't continue replacing different texts using this function.
for example: input is hellookyou and the output is hellohello. the "you" part is missing. could you please explain why it is missing and what I should do. Thanks in advance
//edited this header part, and altered some of the code so that it is buildable
#include <iostream>
#include <conio.h>// for getch() function
std::string replaceOK(std::string a){
char ok[] = "ok";
while(a.find(ok, 0) < a.length()){
a.replace(a.find(ok, 0), a.length() - a.find(ok, 3),"hello");
}
return a;
}
int main(){
std::string a;
std::cin >> a;
a = replaceOK(a);
std::cout << a << std::endl;
return 0;
}
Fixed code.
This won't work if it has the same phrase that I want to change in the resulting changed phrase. It will loop on endlessly.
#include <iostream>
#include <conio.h>// for getch() function
std::string replaceOK(std::string a){
char ok[] = "ok";
while(a.find(ok, 0) < a.length()){
std::cout << "1"; // for visualization of the loop.
a.replace(a.find(ok, 0), a.length() - a.find(ok, 3),"ok1");
// changed "hello" to "ok1"
}
return a;
}
int main(){
std::string a;
std::cin >> a;
a = replaceOK(a);
std::cout << a << std::endl;
return 0;
}

The problem lies in the way you are using the a.replace() function.
The replace() function works in the way
a.replace(0,3,"red") This would change 3 characters from the 0th index and replace them with the string "red".
So in you case you are going to the index where you encounter the first occurence of "ok" string using a.find("ok",0), then by using a.length()-a.find("ok",3), you are getting 5 as the value and replacing them with "hello".
So you are basically doing a.replace(5,5,"hello"). Because of this the "okyou" part gets replaced by "hello" string.
The code is here:
#include <iostream>
#include <conio.h>// for getch() function
using namespace std;
string replaceOK(string a){
string ok = "ok";
int n=a.find("ok",0);
int p=1;//for counting the number of occurence of "ok"
while(n < a.length()){
if(p==1)
a.replace(n,ok.size(),"hello"); //replace 1st occurence of ok to hello
if(p==3)
a.replace(n,ok.size(),"ok1"); //replace 3rd occurence of ok to ok1
if(n+2>=a.length())
break;
n=a.find("ok",n+2);
p+=1;
}
return a;
}
int main(){
string a;
cin >> a;
a = replaceOK(a);
cout << a << std::endl;
return 0;
}

Related

How do I flip the first number in the string with the last number and then second and second last and so on?

Here's what I tried and it's not logical. First_num++ is just copying 2 numbers instead of the second number and so is the last_num++
How do I continue copying like that and cout them
I know I can just cout the thing in reverse because the output is the same.I can do that by reversing the count but the question wants me to exchange the characters one by one. Please help, thanks.
#include <iostream>
#include <cctype>
using namespace std;
void reverse_word(char character[]);
int main()
{
char characters[50];
reverse_word(characters);
return 0;
}
void reverse_word(char character[])
{
char temp1[2] = "\0";
char temp2[2] = "\0";
char first_num = 1;
char last_num = 1;
cout << "Enter a word to reverse first word last word second first second last and so on: ";
cin >> character;
for (int i=0;i<strlen(character)/2;i++)
{
strncpy(temp1, character, first_num);
first_num++;
strcpy(temp2 , &character[strlen(character)-last_num]);
last_num++;
}
for (int i = 0; i < strlen(character) / 2; i++)
{
cout << temp2;
cout << temp1;
}
}
You can use the build-in function of c++ reverse(begin, end) where the begin and end iterator are as parameter like below:
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str = "String example";
reverse(str.begin(), str.end()); // outputs --> elpmaxe gnirtS
cout<<"\n"<<str;
return 0;
}
This is a short and fast solution , but if you want to get a more depth view you can apply some nice alogrithm .
You should cout the temp variables in the same for loop, not in a different one.

Convert char array to a string with cin.getline(.)

hi guys so my question is how to convert a char array to a string. here is my code:
#include<iostream>
using namespace std;
int main()
{
while (true) {
char lol[128];
cout << "you say >> ";
cin.getline(lol,256);
cout << lol << endl;;
}
return 0;
}
so I want to convert lol to a string variable like "stringedChar" (if thats even english lol)
so I can do stuff like:
string badwords[2] = {"frick","stupid"};
for (int counter = 0; counter < 2;counter++) {
if(strigedChar == badwords[counter]) {
bool isKicked = true;
cout << "Inappropriate message!\n";
}
}
Sorry im just a c++ begginer lol
Do something like this :
as char lol[128];
into string like: std::string str(lol);
Line : cin.getline(lol,256); <--> should be changed to cin.getline(lol,128)
Just invoke std::getline() on a std::string object instead of messing about with a char array, and use std::set<std::string> for badwords as testing set membership is trivial:
#include <iostream>
#include <set>
#include <string>
static std::set<std::string> badwords{
"frick",
"stupid"
};
int main() {
std::string line;
while (std::getline(std::cin, line)) {
if (badwords.count(line) != 0) {
std::cout << "Inappropriate message!\n";
}
}
return 0;
}
Note that this tests whether the entire line is equal to any element of the set, not that the line contains any element of the set, but your code appears to be attempting to do the former anyway.
First off, you have a mistake in your code. You are allocating an array of 128 chars, but you are telling cin.getline() that you allocated 256 chars. So you have a buffer overflow waiting to happen.
That said, std::string has constructors that accept char[] data as input, eg:
#include <iostream>
using namespace std;
int main()
{
while (true) {
char lol[128];
cout << "you say >> ";
cin.getline(lol, 128);
string s(lol, cin.gcount());
cout << s << endl;;
}
return 0;
}
However, you really should use std::getline() instead, which populates a std::string instead of a char[]:
#include <iostream>
#include <string>
using namespace std;
int main()
{
while (true) {
string lol;
cout << "you say >> ";
getline(cin, lol);
cout << lol << endl;;
}
return 0;
}

Insert a character into a string

I need to insert a character into a string at every instance of that character. For example if my string was, "This is a test" and my character was 's' then my output would need to look like this: "Thiss iss a tesst"
any idea why this isn't working? Here's what I have so far. I am not supposed to add any extra preprocessor instructions or anything, just using what's here I need to figure this out.
#include <iostream>
#include <string>
using namespace std;
int main(){
string userString;
char userChar;
cin >> userString;
cin >> userChar;
for (int i = 0; i < userString.size(); i++){
if(userString.at(i) == userChar){
userString.insert(userString.begin() + i, userChar);
}
}
cout << userString;
return 0;
Update:
Here's the solution I worked out.
#include <iostream>
#include <string>
using namespace std;
int main(){
string userString;
char userChar;
cout << "enter a string" << endl;
getline(cin, userString);
cout << "enter a character" << endl;
cin >> userChar;
for (int i = userString.size()-1; i >= 0; i--){
if(userString.at(i) == userChar){
userString.insert(userString.begin() + i, userChar);
}
}
cout << userString;
return 0;
}
I don't know why you want to go through the string backwards. Anyway. Your problem is that once you insert a character at some position, your loop will encounter the inserted character again in the next iteration and insert another. Ad infinitum.
#include <cstddef> // std::size_t, the correct type for indexes and sizes of objects in mem
#include <string>
#include <iostream>
int main()
{
std::cout << "Enter a string: ";
std::string userString; // define variables as close
std::getline(std::cin, userString);
std::cout << "Enter a character: ";
char userChar; // to where they're used as possible
std::cin >> userChar;
for (std::size_t i{}; i < userString.size(); ++i) {
if (userString[i] == userChar) { // no need to use std::string::at() 1)
userString.insert(userString.begin() + i, userChar);
++i; // advance the index to not read the same character again.
}
}
std::cout << userString << '\n';
}
1) since it is allready sure that the index will be in a valid range.
Your first solution probably ends up looping infinitely if you ever find one of the chosen character because you always insert one more copy ahead and keeps finding the same char ever after.
std::basic_string has a find function. It's always better to use code offered by a library than self made code. Here's my proposed solution:
std::string& duplicate_char(std::string& str, char val)
{
using std::string;
auto pos = str.find(val); // finds first index of character val or npos if unsuccessful
while (pos != string::npos)
{
str.insert(pos, 1, val); // insert at pos one character val
pos = str.find(val, pos + 2); // find the next occurence of val starting after the newly inserted character
}
return str;
}
You may use this function like this:
int main()
{
std::string testStr{"Thiss iss a tesst"};
duplicate_char(testStr, 's');
std::cout << testStr << std::endl;
}

How to reverse the string

I'm a beginner at coding and was given a project by a friend to reverse the order of a string inputted by the user, however when I run this code the program just repeatedly prints the string inputted many times over and I'm not sure whats wrong.
For instance, I input "hi", it just prints "hi" many times. I have tried using cin, getline and scanf (as recommended by a friend), but to no avail...
#include <iostream>
using namespace std;
int main()
{
char arr[5];
getline(cin, arr);
for(int x=4; x>=0; x--){
cout << arr << endl;
}
return 0;
}
Since the question is tagged C++, you should use C++ constructs such as std::string and std::reverse. This will result in more readable and understandable code.
#include <string>
#include <iostream>
#include <algorithm>
int main()
{
std::string input;
std::getline(std::cin, input);
std::reverse(input.begin(), input.end());
std::cout << input << std::endl;
return 0;
}
This line is wrong:
cout << arr << endl;
You have to use the index operator [] like this:
cout << arr[x];
Note that there is no endl, as that would print every character in a new line.
Using arr[x] gives you the element of the array (or character of the string if you will) at index x. Please note that element indexes in C++ start at 0. So the first element is arr[0], second arr[1], and so on.
Also, why use a C-style char array of only size 5? You can use the C++ std::string just as effectively and it will work for larger strings:
string x;
getline(cin, x);
for (int i = x.size() - 1; i >= 0; i--)
{
cout << x[i];
}
cout << endl;
Hope this helps.
When you write, cout << arr << endl; you are printing the entire string in each iteration of the loop. Instead, you wish to print the character at the index x, so you should write it as cout << arr[x]; If you use endl inside the loop, you will get a new line after each character.
Moreover, in C++, there is an easier way to deal with strings, using the string library. Then, you need not specify the number of characters in your string beforehand, and helps if the user needs to enter more than 4 characters.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string arr;
getline(cin, arr);
for(int x=arr.size()-1; x>=0; x--){
cout << arr[x];
}
cout << endl;
return 0;
}
What's happening is you're sending the entire contents of arr to cout 5 times. What you want instead is to print each character in reverse; to do this, you need to send only one character of arr at a time inside your for loop:
cout << arr[x] // This sends the character at index x to cout
cout << arr // This sends the entire array to cout
Also, you should have cout << endl after the for loop; otherwise, you'll print a newline character after each letter.
Alternate solution using iterators:
#include <iostream>
#include <iterator>
#include <algorithm>
#include <string>
int main()
{
std::string input;
getline(std::cin, input);
for (std::string::reverse_iterator rit=input.rbegin(); rit!=input.rend(); ++rit)
std::cout << *rit;
return 0;
}

How to Convert a C++ String to Uppercase

I need to convert a string in C++ to full upper case. I've been searching for a while and found one way to do it:
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
string input;
cin >> input;
transform(input.begin(), input.end(), input.begin(), toupper);
cout << input;
return 0;
}
Unfortunately this did not work and I received this error message:
no matching function for call to 'transform(std::basic_string::iterator, std::basic_string::iterator, std::basic_string::iterator,
I've tried other methods that also did not work. This was the closest to working.
So what I'm asking is what I am doing wrong. Maybe my syntax is bad or I need to include something. I am not sure.
I got most of my info here:
http://www.cplusplus.com/forum/beginner/75634/
(last two posts)
You need to put a double colon before toupper:
transform(input.begin(), input.end(), input.begin(), ::toupper);
Explanation:
There are two different toupper functions:
toupper in the global namespace (accessed with ::toupper), which comes from C.
toupper in the std namespace (accessed with std::toupper) which has multiple overloads and thus cannot be simply referenced with a name only. You have to explicitly cast it to a specific function signature in order to be referenced, but the code for getting a function pointer looks ugly: static_cast<int (*)(int)>(&std::toupper)
Since you're using namespace std, when writing toupper, 2. hides 1. and is thus chosen, according to name resolution rules.
Boost string algorithms:
#include <boost/algorithm/string.hpp>
#include <string>
std::string str = "Hello World";
boost::to_upper(str);
std::string newstr = boost::to_upper_copy("Hello World");
Convert a String In C++ To Upper Case
Try this small program, straight from C++ reference
#include <iostream>
#include <algorithm>
#include <string>
#include <functional>
#include <cctype>
using namespace std;
int main()
{
string s;
cin >> s;
std::transform(s.begin(), s.end(), s.begin(), std::ptr_fun<int, int>(std::toupper));
cout << s;
return 0;
}
Live demo
You could do:
string name = "john doe"; //or just get string from user...
for(int i = 0; i < name.size(); i++) {
name.at(i) = toupper(name.at(i));
}
Uppercase to Lowercase and viceversa using BitWise operators
1.
string s = "cAPsLock";
for(char &c: s)
c = c | ' '; // similar to: c = tolower(c);
cout << s << endl; // output: capslock
string s = "cAPsLock";
for(char &c: s)
c = c & ~' '; // similar to: c = toupper(c);
cout << s << endl; // output: CAPSLOCK
PS: for more info check this link
#include <iostream>
using namespace std;
//function for converting string to upper
string stringToUpper(string oString){
for(int i = 0; i < oString.length(); i++){
oString[i] = toupper(oString[i]);
}
return oString;
}
int main()
{
//use the function to convert string. No additional variables needed.
cout << stringToUpper("Hello world!") << endl;
return 0;
}
Like leemes said, you can use toupper(int). Like this:
void ToUpper(string &str) {
for (auto beg = str.begin(); beg != str.end(); ++beg) {
*beg = toupper(*beg);
}
}
It'll through in each character from str and convert it to upper. Example:
int main()
{
string name;
cout << "Insert a name: ";
cin >> name;
ToUpper(name);
cout << "Name in upper case: " << name << endl;
}
You can also use the function from code below to convert it to Upper-case.
#include<iostream>
#include<cstring>
using namespace std;
//Function for Converting Lower-Case to Upper-Case
void fnConvertUpper(char str[], char* des)
{
int i;
char c[1 + 1];
memset(des, 0, sizeof(des)); //memset the variable before using it.
for (i = 0; i <= strlen(str); i++) {
memset(c, 0, sizeof(c));
if (str[i] >= 97 && str[i] <= 122) {
c[0] = str[i] - 32; // here we are storing the converted value into 'c' variable, hence we are memseting it inside the for loop, so before storing a new value we are clearing the old value in 'c'.
} else {
c[0] = str[i];
}
strncat(des, &c[0], 1);
}
}
int main()
{
char str[20]; //Source Variable
char des[20]; //Destination Variable
//memset the variables before using it so as to clear any values which it contains,it can also be a junk value.
memset(str, 0, sizeof(str));
memset(des, 0, sizeof(des));
cout << "Enter the String (Enter First Name) : ";
cin >> str; //getting the value from the user and storing it into Source variable.
fnConvertUpper(str, des); //Now passing the source variable(which has Lower-Case value) along with destination variable, once the function is successfully executed the destination variable will contain the value in Upper-Case
cout << "\nThe String in Uppercase = " << des << "\n"; //now print the destination variable to check the Converted Value.
}