Function to replace text in arrays C++ - c++

I am having a problem. I need to make a function called replaceText that replaces a targeted text with new text. The null character is not included and if no targetText is found then there is no text replacement.
The parameters are two arrays targetText[] and replacementText[]. This is for an assignment and I cannot use str. Here is my code so far.
void SimpleString::replaceText(char targetText[], char replacementText[])
{
for ( int i = 0; i < MAX_LIST; i++)
{
if( replacementText[i] > MAX_LIST)
{
throw SimpleStringOverflowException("SimpleStringOverflowException: Resulting SImpleString too large.");
}
}
}

Here you go:
void replace_text(char targetText[], char replacementText[])
{
int i;
if(strlen(replacementText) > 0 )
{
for(i=0;i<strlen(replacementText);i++)
{
targetText[i] = replacementText[i];
}
for(i = strlen(replacementText) ; i < strlen (targetText) ; i++)
targetText[i] = '\0';
}
}
I assume you can use strlen....right? if not let me know...

it is so simple dear, just assign characters one by one.
i.e. targetText[i]=replacementText[i]
now just iterate the i until it ends the replacementtext or targettext.

Related

A quick question from a newbie about deleting non-Upper-alpha: why isn't my code working?

Hi I am trying to delete all the non-capitalized alphabet from a string input, but I am not quite sure where the error is in my coding. Please comment if you know why!
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
string CreateAcronym(string userPhrase) {
int i;
int stringSize;
char charAti;
stringSize = userPhrase.size();
for (i=0 ; i < stringSize ; i++ ) {
charAti = userPhrase.at(i);
if ( !isupper(charAti)) {
userPhrase.erase(i,1);
}
}
return userPhrase;
}
int main() {
string userSentence;
getline(cin , userSentence);
cout << CreateAcronym(userSentence) << endl;
return 0;
}
You cached old string length and continued to use while the string will become shorter by erasing characters.
You skip characters after characters to erase because i++ isn't canceled after erasure.
stringSize = userPhrase.size();
for (i=0 ; i < stringSize ; i++ ) {
charAti = userPhrase.at(i);
if ( !isupper(charAti)) {
userPhrase.erase(i,1);
}
}
should be
for (i=0 ; i < static_cast<int>(userPhrase.size()) ; ) {
charAti = userPhrase.at(i);
if ( isupper(charAti)) {
i++;
} else {
userPhrase.erase(i,1);
}
}
The problem have been answered by others, so I just add my "simpler" solution to the problem:
string CreateAcronym(string userPhrase) {
string result; // Create an empty string
// Loop over all the characters in the original string
for (char c : userPhrase) {
// If the character is upper-case...
if (isupper(c))
result += c; // Append it to the new string
}
return result; // Return the new string
}
You have 2 issues in your code.
First, you are erasing the string inside the loop (which changes its length), but using the precalculated length in the comparison.
Second, you only need to increment i when you don't erase a character. Otherwise, you will skip over some characters.
A working loop would be:
for (i = 0; i < userPhrase.size();) {
charAti = userPhrase.at(i);
if ( !isupper(charAti)) {
userPhrase.erase(i,1);
}
else {
++i;
}
}
You could simplify this loop by using an algoritm:
string CreateAcronym(string userPhrase) {
userPhrase.erase(std::remove_if(userPhrase.begin(),
userPhrase.end(), [](auto charAti) {
return !isupper(charAti); }),
userPhrase.end());
return userPhrase;
}
Here's a demo.

I do not understand why these two functions dont both work

The first function will appropriately change the universal variable chosenWord, but the second will not affect guessedWord at all. I understand that the functions are just copying the values of the variables, but why does it work in the first but not the second? And, how do I make the second one work?
void lowerCase() //Convert inputted word to lowercase
{
int x = 0;
while(chosenWord[x])
{
chosenWord[x] = tolower(chosenWord[x]);
x++;
}
}
void setupGuessString() //Set guessed word to same length as chosen word and replace each letter with '_'
{
int x = 0;
while(chosenWord[x])
{
guessedWord[x] = '_';
x++;
}
}
as defined in another .cpp (for practice):
std::string chosenWord;
std::string guessedWord;
as declared in a .h (again, for practice):
extern std::string chosenWord;
extern std::string guessedWord;
As I understand guessedWord is an empty string string guessedWord = ""; so to set it up you need to add '_' characters to guessedWord, not to set them equal to '_'. So your function will be:
void setupGuessString()
{
int x = 0;
while (chosenWord[x]))
{
guessedWord += '_';
}
}
And I would strongly recommend not to use global variables, instead of them use the return statement, that is just a better practise. So your functions will be:
string lowerCase(string chosenWord)
{
int x = 0;
while(chosenWord[x])
{
chosenWord[x] = tolower(chosenWord[x]);
x++;
}
return chosenWord;
}
string setupGuessString(string chosenWord)
{
int x = 0;
string guessedWord = "";
while (chosenWord[x]))
{
guessedWord += '_';
}
return guessedWord;
}
Hope this helps.
Is guessedWord of type character array ?
Is it global array ?
#include <stdio.h>
char *chosenWord = "Hello W";
char guessedWord[10];
void setupGuessString() //Set guessed word to same length as chosen word and replace each letter with '_'
{
int x = 0;
while(chosenWord[x])
{
guessedWord[x] = '_';
x++;
}
guessedWord[x] = '\0';
}
int main()
{
setupGuessString();
printf("%s ;; %s",chosenWord, guessedWord);
return 0;
}
This is the output I see.. :
Hello W ;; _______ <--- this

Merge sort the character in a std:string

So I am trying to Merge Sort the letters of a string so that they are in order. Capitalization does not matter since the homework does not require it. For some reason I cannot get templet[index] = split[leftfirst]. I get an "no suitable conversion function from std::string to char exists". Heres my merge function
void merge(string *split, int leftfirst, int leftlast, int rightfirst, int rightlast)
{
string templet;
int index = leftfirst;
int savefirst = leftfirst;
while ((leftfirst <= leftlast) && (rightfirst <= rightlast))
{
if (split[leftfirst] < split[rightfirst])
{
templet[index] = split[leftfirst];
leftfirst++;
}
else
{
templet[index] = split[rightfirst];
rightfirst++;
}
index++;
}
while (leftfirst <= leftlast)
{
templet[index] = split[leftfirst];
leftfirst++;
index++;
}
while (rightfirst <= rightlast)
{
templet[index] = split[rightfirst];
rightfirst++;
index++;
}
for (index = savefirst; index <= rightlast; index++)
split[index] = templet[index];
}
Any help is appreciated.
split is a string*, which means split[some] will not get a character out of the string, it will rather get a string from a string array.
Easiest way to fix this is to change the function definition to have string &split, if you want to modify the variable.

How to delete characters in vector of strings?

I am writing a code where I read a subtitle file and remove the text in () including the brackets themselves, that is subtitles for hearing impaired which have background noise in ().
The example:
13
00:01:08,535 --> 00:01:10,127 // remove this
(PIANO PLAYING) // remove this
125
00:07:09,162 --> 00:07:12,393
BOTH: (SINGING WITH RADIO) Teach // remove only the text in parenthesis, including ()
them well and let them lead the way
The code is here:
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
using namespace std;
void subRem();
int main() {
subRem();
system("PAUSE");
}
void subRem() {
ofstream out;
ifstream in;
out.open("whip it2.srt");
if (out.fail()) {
perror("whip it2.srt");
}
in.open("whip it.srt");
if (out.fail()) {
perror("whip it.srt");
}
vector<string> input;
string inc;
while (getline(in, inc)) {
input.push_back(inc);
}
vector<int> len;
for (int i = 0; i < input.size(); i++) {
len.push_back(input[i].size());
}
for (int i = 0; i < input.size(); i++) {
for (int j = 0; j < len[i]; j++) {
if (input[i][j] == '(') {
for (int k = j; k < len[i]; k++) {
j = k;
if (input[i][k] == ')') {
if (k == (len[i] - 1)) {
input[i - 1] = "";
}
input[i][k] = '\0';
break;
}
input[i][k] = '\0';
}
}
}
}
for (int k = 0; k < input.size(); k++) {
out << input[k] << endl;
}
}
I want to delete the characters in parenthesis, so I am using:
input[i][k] = '\0';
The problem is the characters are removed but they are replaced by whitespace, for example:
(SHOUTING) with her?
I get:
___________with her?
(____ are whitespaces because I couldn't make them appear)
There is the white space. If it was string, I could do:
input[i][k] = "";
but with characters I get the error when I do:
input[i][k] = '';
quoted string should contain at least one character
I plan to improve the code further by renaming the line numbers and deleting extra newlines, but I want to create like an app where I can drag and drop the subtitle file and click run, to get the modified subtitle file. What do I need to know to create the GUI? Do I need to learn Qt or some other libraries?
std:;string can contain \0 without problems, it's not the end-of-string character inside a std::string. MikeCAT's suggestion is the correct answer: use std::string::erase.
(Please don't ask multiple questions at once, but yes Qt is a reasonable way to create GUI's)
Try using substr. This method gives you a substring between two given positions. Although this solves the problem for your second problem, it leaves empty subtitles for strings on the first case. I would recommend checking for an empty result and removing the string at all.
Since you're basically copying characters from one file to another, I'd just keep track of whether you're in a subtitle as you copy, and if so, don't copy characters until you encounter a close parenthesis again.
#include <string>
#include <iostream>
#include <sstream>
int main() {
std::istringstream in{
R"(13
00:01:08,535 --> 00:01:10,127
(PIANO PLAYING)
125
00:07:09,162 --> 00:07:12,393
BOTH: (SINGING WITH RADIO) Teach
them well and let them lead the way)"
};
bool in_subtitle = false;
std::string temp;
while (std::getline(in, temp)) {
unsigned line_len = 0;
for (char ch : temp) {
switch (ch) {
case '(': in_subtitle = true; break;
case ')': in_subtitle = false; break;
default:
if (!in_subtitle) {
std::cout << ch;
++line_len;
}
break;
}
}
if (line_len != 0) std::cout << "\n";
}
}
#include <iostream>
#include <regex>
int main() {
std::string text("this text (remove this) and (remove this) end.");
// First Method: with regular expression
std::regex expr("\\(.*?\\)");
std::cout << std::regex_replace (text, expr, "");
// Second Method: with stl
auto begin = text.find_first_of("(");
auto end = text.find_last_of(")") + 1;
if (std::string::npos != begin && std::string::npos != end && begin <= end)
text.erase(begin, end-begin);
// Optional
std::cout << text << std::endl;
}

How to declare an empty char* and increase the size dynamically?

Let's say I am trying to do the following (this is a sub problem of what I am trying to achieve):
int compareFirstWord(char* sentence, char* compareWord){
char* temp; int i=-1;
while(*(sentence+(++i))!=' ') { *(temp+i) = *(sentence+i); }
return strcmp(temp, compareWord); }
When I ran compareFirstWord("Hi There", "Hi");, I got error at the copy line. It said I was using temp uninitialized. Then I used char* temp = new char[]; In this case the function returned 1 and not 0. When I debugged, I saw temp starting with some random characters of length 16 and strcmp fails because of this.
Is there a way to declare an empty char* and increase the size dynamically only to length and contents of what I need ? Any way to make the function work ? I don't want to use std::string.
In C, you may do:
int compareFirstWord(const char* sentence, const char* compareWord)
{
while (*compareWord != '\0' && *sentence == *compareWord) {
++sentence;
++compareWord;
}
if (*compareWord == '\0' && (*sentence == '\0' || *sentence == ' ')) {
return 0;
}
return *sentence < *compareWord ? -1 : 1;
}
With std::string, you just have:
int compareFirstWord(const std::string& sentence, const std::string& compareWord)
{
return sentence.compare(0, sentence.find(" "), compareWord);
}
temp is an uninitialized variable.
It looks like you are attempting to extract the first word out of the sentence in your loop.
In order to do it this way, you would first have to initialize temp to be at least as long as your sentence.
Also, your sentence may not have a space in it. (What about period, \t, \r, \n? Do these matter?)
In addition, you must terminate temp with a null character.
You could try:
int len = strlen(sentence);
char* temp = new char[len + 1];
int i = 0;
while(i < len && *(sentence+(i))!=' ') {
*(temp+i) = *(sentence+i);
i++;
}
*(temp+i) = '\0';
int comparable = strcmp(temp, compareWord);
delete temp;
return comparable;
Also consider using isspace(*(sentence+(i))), which will at least catch all whitespace.
In general, however, I'd use a library, or STL... Why reinvent the wheel...