why there is an error in my removestring function - c++

I am making a function called removeString(). It's purpose is to remove a string from a text
example: if the text is "the wrong son" and I want to remove "wrong" to be "the son", I use this function.
The prototype is:
void removeString(char source[], int start, int numofchrem);
and the program is like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void removeString(char source[], int start, int numofchrem)
{
int i, j, k;
char n[20];
j = start + numofchrem - 1;
for (i = 0; i < numofchrem; i++)
{
if (source[start] == '\0')
break;
source[j] = '\b';
j--;
}
printf("%s", source);
}
int main()
{
char text[] = "the wrong son";
void removeString(char source[], int start, int numofchrem);
removeString(text, 4, 6);
}
when I made the program I debugged first the characters inside the source it was like this
"the \b\b\b\b\b\bson"
When I print the text inside source using:
printf("%s",source);
The program showed only "son" not "the son". So if anyone could help me I would be so grateful.

You need to move "son" (and the '\0') back, over what you want to replace
void removeString(char source[], int start, int numofchrem)
{
char *d = source + start; // d points to "wrong..."
char *s = source + start + numofchrem; // s points to "son"
while (*s != '\0') {
*d = *s; // replace 'w' with 's', 'r' with 'o', ...
d++; // point to next: "rong...", "ong...", "ng..."
s++; // point to next: "on", "n"
}
*d = '\0'; // terminate string
}

Related

How to split a string by another string in Arduino?

I have a character array like below:
char array[] = "AAAA... A1... 3. B1.";
How can I split this array by the string "..." in Arduino? I have tried:
ptr = strtok(array, "...");
and the output is the following:
AAAA,
A1,
3,
B1
But I actually want output to be
AAAA,
A1,
3.B1.
How to get this output?
edit:
My full code is this:
char array[] = "AAAA... A1... 3. B1.";
char *strings[10];
char *ptr = NULL;`enter code here`
void setup()
{
Serial.begin(9600);
byte index = 0;
ptr = strtok(array, "..."); // takes a list of delimiters
while(ptr != NULL)
{
strings[index] = ptr;
index++;
ptr = strtok(NULL, "..."); // takes a list of delimiters
}
for(int n = 0; n < index; n++)
{
Serial.println(strings[n]);
}
}
The main problem is that strtok does not find a string inside another string. strtok looks for a character in a string. When you give multiple characters to strtok it looks for any of these. Consequently, writing strtok(array, "..."); is exactly the same as writing strtok(array, ".");. That is why you get a split after "3."
There are multiple ways of doing what you want. Below I'll show you an example using strstr. Unlike strtokthe strstr function do find a substring inside a string - just what you are looking for. But.. strstr is not a tokenizer so some extra code is required to print the substrings.
Something like this should do:
int main()
{
char array[] = "AAAA... A1... 3. B1...";
char* ps = array;
char* pf = strstr(ps, "..."); // Find first substring
while(pf)
{
int len = pf - ps; // Number of chars to print
printf("%.*s\n", len, ps);
ps = pf + 3;
pf = strstr(ps, "..."); // Find next substring
}
return 0;
}
You can implement your own split as strtok except the role of the second argument :
#include <stdio.h>
#include <string.h>
char * split(char *str, const char * delim)
{
static char * s;
char * p, * r;
if (str != NULL)
s = str;
p = strstr(s, delim);
if (p == NULL) {
if (*s == 0)
return NULL;
r = s;
s += strlen(s);
return r;
}
r = s;
*p = 0;
s = p + strlen(delim);
return r;
}
int main()
{
char s[] = "AAAA... A1... 3. B1.";
char * p = s;
char * t;
while ((t = split(p, "...")) != NULL) {
printf("'%s'\n", t);
p = NULL;
}
return 0;
}
Compilation and execution:
/tmp % gcc -g -pedantic -Wextra s.c
/tmp % ./a.out
'AAAA'
' A1'
' 3. B1.'
/tmp %
I print between '' to show the return spaces, because I am not sure you want them, so delim is not only ... in that case
Because you tagged this as c++, here is a c++ 'version' of your code:
#include <iostream>
using std::cout;
using std::endl;
#include <vector>
using std::vector;
#include <string>
using std::string;
class T965_t
{
string array;
vector<string> strings;
public:
T965_t() : array("AAAA... A1... 3. B1.")
{
strings.reserve(10);
}
~T965_t() = default;
int operator()() { return setup(); } // functor entry
private: // methods
int setup()
{
cout << endl;
const string pat1 ("... ");
string s1 = array; // working copy
size_t indx = s1.find(pat1, 0); // find first ... pattern
// start search at ---------^
do
{
if (string::npos == indx) // pattern not found
{
strings.push_back (s1); // capture 'remainder' of s1
break; // not found, kick out
}
// else
// extract --------vvvvvvvvvvvvvvvvv
strings.push_back (s1.substr(0, indx)); // capture
// capture to vector
indx += pat1.size(); // i.e. 4
s1.erase(0, indx); // erase previous capture
indx = s1.find(pat1, 0); // find next
} while(true);
for(uint n = 0; n < strings.size(); n++)
cout << strings[n] << "\n";
cout << endl;
return 0;
}
}; // class T965_t
int main(int , char**) { return T965_t()(); } // call functor
With output:
AAAA
A1
3. B1.
Note: I leave changing "3. B1." to "3.B1.", and adding commas at end of each line (except the last) as an exercise for the OP if required.
I looked for a split function and I didn't find one that meets my requirement, so I made one and it works for me so far, of course in the future I will make some improvements, but it got me out of trouble.
But there is also the strtok function and better use that.
https://www.delftstack.com/es/howto/arduino/arduino-strtok/
I have the split function
Arduino code:
void split(String * vecSplit, int dimArray,String content,char separator){
if(content.length()==0)
return;
content = content + separator;
int countVec = 0;
int posSep = 0;
int posInit = 0;
while(countVec<dimArray){
posSep = content.indexOf(separator,posSep);
if(posSep<0){
return;
}
countVec++;
String splitStr = content.substring(posInit,posSep);
posSep = posSep+1;
posInit = posSep;
vecSplit[countVec] = splitStr;
countVec++;
}
}
Llamada a funcion:
smsContent = "APN:4g.entel;DOMAIN:domolin.com;DELAY_GPS:60";
String vecSplit[10];
split(vecSplit,10,smsContent,';');
for(int i = 0;i<10;i++){
Serial.println(vecSplit[i]);
}
String input:
APN:4gentel;DOMAIN:domolin.com;DELAY_GPS:60
Output:
APN:4g.entel
DOMAIN:domolin.com
DELAY_GPS:60
RESET:true
enter image description here

C++ error: expected ',' or ';' before '{' token when their is

I am trying to create a function that will return the alphabet position of a letter that is passed into the function
for example
cout<<getPosition('l')
would return the integer 12. I am fairly certain I have got the logic correct however I am having some trouble with the syntax. I found many similar questions however I still was not able to solve the problem.
Any help appreciated
#include <iostream>
using namespace std;
int getPosition(letter)
{
int pos = 0;
const char alphabet[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
for (int counter=0; counter!=26; counter++)
{
if (alphabet[counter] == letter)
{
pos = counter;
break;
}
}
return pos;
}
int main()
{
string letter = 'r';
cout << posInAlpha(letter);
return 0;
}
You are mixing std::string and char, while you don't need the first. Moreover, your main() uses a function not declared. Furthermore, your function's parameter lacks it's type. Your compiler should be pretty explanatory for these. I modified your code to get the desired behavior; please take a moment or two understanding what had to be modified here:
#include <iostream>
using namespace std;
// Returns the index of 'letter' in alphabet, or -1 if not found.
int getPosition(char letter)
{
int pos = -1;
const char alphabet[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
for (int counter=0;counter!=26;counter++)
{
if (alphabet[counter]==letter)
{
pos=counter;
break;
}
}
return pos;
}
int main()
{
char letter='r';
cout<<getPosition(letter);
return 0;
}
Output:
17
I initialized pos to -1, in case letter does not belong in the alphabet. Otherwise the function would return 0, meaning that a was the answer.
PS: If letter was an std::string, then your comparison with every letter of the alphabet would produce a compilation error, since the types do not match.
it all begins here
int getPosition(letter)
{
this function is not right declared/defined, letter must be a type and you just gave none...
assuming this
char letter = 'r';
cout << posInAlpha(letter);
that letter must be a char and the function posInAlpha should be renamed to getPosition
it all looks like you are mixing std::strings and chars,
your final fixed code should look like:
#include <iostream>
using namespace std;
int getPosition(char& letter)
{
int pos = 0;
const char alphabet[26] = { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z' };
for (int counter = 0; counter != 26; counter++)
{
if (alphabet[counter] == letter)
{
pos = counter;
break;
}
}
return pos;
}
int main()
{
char letter = 'r';
cout << getPosition(letter);
cin.get();
return 0;
}
which prints 17 for the given char 'r'
#include <iostream>
int getPosition( char c )
{
c |= 0x20; // to lower
return ( c < 'a' || c > 'z' )
? -1
: c - 'a';
}
int main()
{
std::cout << getPosition( 'R' );
return 0;
}
Demo

How to make recursive function, it needs to check if in a given string the current letter and the one next to it is either lowercase or upper case?

It should convert a string like this: Example: HEloOO, should be converted into : heLOoo . For some reason it doesn't work,it just wont convert the letters from uppercase to lowercase and vice versa any help would be appreciated ?
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void rek(char array[], int d)
{
int counter=0;
if(d==0)
{
printf("%s \n",array);
printf("%d \n",counter);
}
else
{
if((array[d]>='A' && array[d]<='Z')&&(array[d-1]>='A' && array[d-1]<='Z'))
{
array[d]=array[d]+32;
array[d-1]=array[d-1]+32;
counter++;
rek(array,d-2);
}
if((array[d]>='a' && array[d]<='z')&&(array[d-1]>='a' && array[d-1]<='z'))
{
array[d]=array[d]-32;
array[d-1]=array[d-1]-32;
counter++;
rek(array,d-2);
}
}
}
int main()
{
char array[100];
int d;
gets(array);
d=strlen(array);
rek(array,d);
return 0;
}
Your function does not call itself when two adjacent characters have different cases. Also you can get different results when the string is processed from the start or from the end.
I would write the function the following way
#include <stdio.h>
#include <ctype.h>
char * rek(char *s)
{
if (s[0] && s[1])
{
size_t i = 1;
if (islower((unsigned char)s[0]) && islower((unsigned char)s[1]))
{
s[0] = toupper((unsigned char)s[0]);
s[1] = toupper((unsigned char)s[1]);
++i;
}
else if (isupper((unsigned char)s[0]) && isupper((unsigned char)s[1]))
{
s[0] = tolower((unsigned char)s[0]);
s[1] = tolower((unsigned char)s[1]);
++i;
}
rek(s + i);
}
return s;
}
int main( void )
{
char s[] = "HEloOO";
puts(rek(s));
return 0;
}
The program output is
heLOoo
The main problem is that you recur only if your have a pair of upper-case or lower-case letters. Otherwise, you drop off the end of your if, return to the calling program, and quit converting things.
The initial problem is that you've indexed your string with the length. A string with 6 characters has indices 0-5, but you've started with locations 5 and 6 -- the final 'O' and the null character.
The result is that you check 'O' and '\0'; the latter isn't alphabetic at all, so you drop through all of your logic without doing anything, return to the main program, and finish.
For future reference, Here's the debugging instrumentation I used. Also see the canonical SO debug help.
#include<stdio.h>
#include<string.h>
#include<ctype.h>
void rek(char array[], int d)
{
int counter=0;
printf("ENTER rek %s %d\n", array, d);
if(d==0)
{
printf("%s \n",array);
printf("%d \n",counter);
}
else
{
printf("TRACE 1: %d %c%c\n", d, array[d-1], array[d]);
if((array[d]>='A' && array[d]<='Z')&&(array[d-1]>='A' && array[d-1]<='Z'))
{
printf("TRACE 2: upper case");
array[d]=array[d]+32;
array[d-1]=array[d-1]+32;
counter++;
rek(array,d-2);
}
if((array[d]>='a' && array[d]<='z')&&(array[d-1]>='a' && array[d-1]<='z'))
{
printf("TRACE 3: lower case");
array[d]=array[d]-32;
array[d-1]=array[d-1]-32;
counter++;
rek(array,d-2);
}
}
}
int main()
{
char *array;
int d;
array = "HEloOO";
d=strlen(array);
rek(array,d);
printf("%s\n", array);
return 0;
}
I come up with this dirty solution:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
string solve(const string& str)
{
if (str.empty()) {
return "";
}
if (str.front() >= 'a' && str.front() <= 'z') {
return (char)toupper(str.front()) + solve(str.substr(1));
}
if (str.front() >= 'A' && str.front() <= 'Z') {
return (char)tolower(str.front()) + solve(str.substr(1));
}
}
int main()
{
string str;
cin >> str;
cout << solve(str) << endl;
return 0;
}

Replacing character in string in cpp using pointer

I am very new new to cpp and trying to replace second occurrence of '*' with '!' char in a given string using following method.
#include <iostream>
#include <string.h>
using namespace std;
void replaceChar(char **inp){
char *tmp = *inp;
const char *c = "*";
char *cmark = strstr(tmp,c);
cout<< *cmark;
if(cmark != NULL && strlen(cmark) > 1){
cmark++;
if(strstr(cmark,c)){
int len = strlen(cmark);
cout<<"len"<<len;
for(int i=0;i<len;i++){
if(cmark[i] == '*'){
cout<<"i.."<<i;
cmark[i] = '!';//error point
}
}
}
}
}
int main() {
char * val = "this is string*replace next * with ! and print";
replaceChar(&val);
cout<<"val is "<< val;
return 0;
}
I am getting run time error on error point line.If I comment out this line I am getting correct index of '*' to be replaced.
Is it possible to replace '*' with '!' using cmark[i] = '!'?
Check this difference between char s[] and char *s in C
#include <iostream>
#include <string.h>
using namespace std;
void replaceChar(char *inp){
char *tmp = inp;
const char *c = "*";
char *cmark = strstr(tmp,c);
cout<< *cmark;
if(cmark != NULL && strlen(cmark) > 1){
cmark++;
if(strstr(cmark,c)){
int len = strlen(cmark);
cout<<"len"<<len;
for(int i=0;i<len;i++){
if(cmark[i] == '*'){
cout<<"i.."<<i;
cmark[i] = '!';
}
}
}
}
}
int main() {
char val[] = "this is string*replace next * with ! and print";
replaceChar(val);
cout<<"val is "<< val;
return 0;
}
There is no need to pass pointer to pointer in method.
Instead you can just pass original pointer to string.
You can do it in much simpler way.
void replaceChar(char *inp){
int i;
int second = 0;
/* Strings in C\C++ is null-terminated so we use it to determine
end of string */
for (i = 0; inp[i] != '\0'; ++i) {
if (inp[i] == '*') {
/* Use flag to determine second occurrence of * */
if (!second) {
second = 1;
} else {
inp[i] = '!';
break;
}
}
}
}

I get a number 2 when I reverse my string

I wrote this code to reverse strings. It works well, but when I enter short strings like "american beauty," it actually prints "ytuaeb nacirema2." This is my code. I would like to know what is wrong with my code that prints a random 2 at the end of the string. Thanks
// This program prompts the user to enter a string and displays it backwards.
#include <iostream>
#include <cstdlib>
using namespace std;
void printBackwards(char *strPtr); // Function prototype
int main() {
const int SIZE = 50;
char userString[SIZE];
char *strPtr;
cout << "Please enter a string (up to 49 characters)";
cin.getline(userString, SIZE);
printBackwards(userString);
}
//**************************************************************
// Definition of printBackwards. This function receives a *
// pointer to character and inverts the order of the characters*
// within it. *
//**************************************************************
void printBackwards(char *strPtr) {
const int SIZE = 50;
int length = 0;
char stringInverted[SIZE];
int count = 0;
char *strPtr1 = 0;
int stringSize;
int i = 0;
int sum = 0;
while (*strPtr != '\0') {
strPtr++; // Set the pointer at the end of the string.
sum++; // Add to sum.
}
strPtr--;
// Save the contents of strPtr on stringInverted on inverted order
while (count < sum) {
stringInverted[count] = *strPtr;
strPtr--;
count++;
}
// Add '\0' at the end of stringSize
stringInverted[count] == '\0';
cout << stringInverted << endl;
}
Thanks.
Your null termination is wrong. You're using == instead of =. You need to change:
stringInverted[count] == '\0';
into
stringInverted[count] = '\0';
// Add '\0' at the end of stringSize
stringInverted[count] == '\0';
Should use = here.
What is wrong with your code is that you do not even use strlen for counting the length of the string and you use fixed size strings (no malloc, or, gasp new[]), or the std::string (this is C++)! Even in plain C, not using strlen is always wrong because it is hand-optimized for the processor. What is worst, you have allocated the string to be returned (stringInverted) from the stack frame, which means when the function exits, the pointer is invalid and any time the code "works" is purely accidental.
To reverse a string on c++ you do this:
#include <iostream>
#include <string>
int main() {
std::string s = "asdfasdf";
std::string reversed (s.rbegin(), s.rend());
std::cout << reversed << std::endl;
}
To reverse a string in C99 you do this:
char *reverse(const char *string) {
int length = strlen(string);
char *rv = (char*)malloc(length + 1);
char *end = rv + length;
*end-- = 0;
for ( ; end >= rv; end --, string ++) {
*end = *string;
}
return rv;
}
and remember to free the returned pointer after use. All other answers so far are blatantly wrong :)