I wrote this code to remove all occurrences of x from the string using recursion
#include <bits/stdc++.h>
using namespace std;
void removex(string str)
{
if (str.length()==0)
{
return;
}
if (str[0] != 'x')
{
removex(str.substr(1,str.length()));
}
int i = 1;
for (; str[i] != '\0'; i++)
{
str[i-1]=str[i];
}
str[i - 1] = str[i];
removex(str);
// cout<<"strq"<<str<<endl;
}
int main()
{
int t;
cin >> t;
while (t--)
{
string str;
cin >> str;
removex(str);
cout << str << endl;
}
return 0;
}
however it's pass by value and If I try using pass by reference it gives an error as
initial value of reference to non-const must be an lvalueC. which means I need to make the reference constant which is not suitable for rest of the code. I tried pass by pointer and using arrow operator however unable to get value at index and not sure how to make recursion call. to pass address or ponter? can someone modify it accordingly?
Doing this with std::string and recursion is a formidable template for insanity. The erase/remove idiom exists for just this purpose, functions iteratively, and is highly efficient. Best of all, it already exists; all you have to do is set up the calls.
That said, if you're bent on doing this recursively (and inefficiently) you need to convey the result back to the caller (including the recursive calls) somehow. The following does that using the function return type, which is std::string. This also uses the global free operator + that allows concatenation of a char + std::string to return a new string:
#include <iostream>
#include <string>
std::string removex(std::string str)
{
if (!str.empty())
{
if (str[0] == 'x')
str = removex(str.substr(1));
else
str = str[0] + removex(str.substr(1));
}
return str;
}
int main()
{
std::string str = "Remove all x chars from this string.";
std::cout << "Before: " << str << '\n';
std::cout << "After: " << removex(str) << '\n';
return 0;
}
Output
Before: Remove all x chars from this string.
After: Remove all chars from this string.
That said, that isn't the way I'd do this. I'd use the erase/remove idiom which would be much faster, and much more memory efficient.
Given that you are using C++, I would use the features of the standard library. I believe this problem can be easily solved with a single line of code. Assuming that the string variable is called line, you would just need to do something like:
line.erase(remove(line.begin(), line.end(), 'x'), line.end());
Following is a complete example:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
std::string line = "12djd V x jhrf h58HSFH HUHFuhfdhkdh uhdfvygh 234 fhj xxx";
std::cout << "Line before removing the x character: " << line << std::endl;
line.erase(remove(line.begin(), line.end(), 'x'), line.end());
std::cout << "Line after removing the x character: " << line << std::endl;
return 0;
}
The example above would produce the following output:
Line before removing the x character: 12djd V x jhrf h58HSFH HUHFuhfdhkdh uhdfvygh 234 fhj xxx
Line after removing the x character: 12djd V jhrf h58HSFH HUHFuhfdhkdh uhdfvygh 234 fhj
An example that you can run is available here: https://onlinegdb.com/4wzMXTXP5
Related
Sorry for the noob question, I'm a newbie programmer and transitioning from C to C++.
I could easily write a program to reverse a string in C the same way with minor changes but writing this in C++, why does this not print anything:
#include <iostream>
#include <string>
using namespace std;
int main(){
string s,p;
getline(cin,s);
int j=0,i = 0;
while(s[i]!='\0'){
i++;
}
i--;
while(i!=-1){
p[j] = s[i];
j++;
i--;
}
cout << p << endl;
return 0;
}
if i replace the p with say p[2], it correctly prints out the reverse 3rd character of the original string, but i cant find a way to print the whole string.
std::string str{"reverse me"};
std::string rev{str.rbegin(), str.rend()};
//or when you are not interested in the orignal string
std::reverse(str.begin(), str.end());
Giving the constructur of the reverse string the reversed iterators of your input string gives you the string in reversed order.
To fix your string reverse code you just have to resize the string object p:
int main(){
std::string s = "hello",
p;
p.resize(s.size()); // this was causing your problems, p thought it was size 0
for (int i = s.size() - 1, j = 0; i >= 0; i--, j++)
{
p[j] = s[i];
}
std::cout << p << std::endl;
return 0;
}
In addition to this, there is no need to find \0 in the string, while it will be there, you can just ask std::string what its size() is.
On a side note, while std::string probably allocates some memory by default, just assuming it has enough to store whatever you input is going to be undefined behaviour.
While there are ways to iterate over a std::string and fill the contents of another, the overload of std::basic_string::operator= will replace the content of p (if any) with the content of s in a simple assignment. See std::basic_string::operator=
For example:
#include <iostream>
#include <string>
int main (void) {
std::string s {}, p {};
std::cout << "enter string: ";
if (getline (std::cin, s)) {
p = s; /* simple assignment replaced content of p with content of s */
std::cout << "string in p : " << p << '\n';
}
}
Example Use/Output
$ ./bin/stringps
enter string: the string s
string in p : the string s
string p; doesn't have enough allocated space for directly accessing by something like p[j]
You can change to initialize p from copying s like below, your code will work.
string s;
getline(cin,s);
string p(s); // p will be allocated and be the same as s
I have the following code which converts a std::string to ASCII hex output, the code is running fine but there is one small problem. It is not converting the space to hex. How can I solve that problem.
#include <iostream>
#include <string>
#include <sstream>
int main(){
std::string text = "This is some text 123...";`
std::istringstream sin(text);
std::ostringstream sout;
char temp;
while(sin>>temp){
sout<<"x"<<std::hex<<(int)temp;
}
std::string output = sout.str();
std::cout<<output<<std::endl;
return 0;
}
Instead of all that mechanism to create an input stream, use iterators:
template <class Iter>
void show_as_hex(Iter first, Iter last) {
while (first != last) {
std::cout << 'x' << std::hex << static_cast<int>(*first) << ' ';
++first;
}
std::cout << '\n';
}
int main() {
std::string text = "This is some text 123...";
show_ask_hex(text.begin(), text.end());
return 0;
}
This avoids the complexity of stream input, and, in particular, the fact that stream extractors (operator>>) skip whitespace.
operator >> of streams skips white space by default. This means when it hits a space in your string it is just going to skip it and move to the next non white space character. Fortunately there is no reason to even use a stringstream here. We can use just a plain ranged based for loop like
int main()
{
std::string text = "This is some text 123...";`
for (auto ch : test)
cout << "x" << std::hex << static_cast<int>(ch);
return 0;
}
This will convert every character in the string into a int and then output that out to cout.
I want to ask for word from the user and then convert the word from string to char using 'strcpy'. Then I want to determine the sum of the ascii codes for all of the letters in the word.
However, I am having difficulties. I don't understand exactly how I can do that. This is what I have been able to do so far.
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
int main()
{
string word;
cout << "Enter word: ";
getline(cin, word);
/*
char w[word];
strcpy(w,word.c_str());
int ('A');
cout<<char(65);
*/
return 0;
}
The commented part is where I have been trying to do the converting. I copied the code from a worksheet. Even if it did work, I don't know how, and what it all means.
Thanks for your help.
char w[word];
strcpy(w, word.c_str());
char w[word] is incorrect. The square brackets is for the size, which must be a constant integral expression. word is of type std::string, so this makes neither logical nor practical sense. Maybe you meant it as:
char w = word;
But that still won't work because word is a string, not a character. The correct code in this case is:
char* w = new char[word.size() + 1];
That is, you allocate the memory for w using a char*. Then you use word.size() + 1 to initialize heap-allocated memory amounting to those bytes. Don't forget for the obligatory delete[] when you're finished using w:
delete[] w;
However, note that using raw pointers and explicit new is not needed in this case. Your code can easily be cleaned up into the following:
#include <numeric>
int main ()
{
std::string word;
std::getline(std::cin, word);
int sum = std::accumulate(word.begin(), word.end(), 0); /*
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
std::cout << "The sum is: " << sum << std::endl;
}
You don't need to use strcpy() (or use a char * at all, for that matter), but this'll do your counting using a char pointer:
#include <iostream>
#include <string>
int main() {
std::string word;
std::cout << "Enter word: ";
std::cin >> word;
const char * cword = word.c_str();
int ascii_total = 0;
while ( *cword ) {
ascii_total += *cword++;
}
std::cout << "Sum of ASCII values of characters is: ";
std::cout << ascii_total << std::endl;
return 0;
}
Output:
paul#local:~/src/cpp/scratch$ ./asccount
Enter word: ABC
Sum of ASCII values of characters is: 198
paul#local:~/src/cpp/scratch$
If you really do want to use strcpy(), I'll leave it as an exercise to you to modify the above code.
Here's a better way to do it, just using std::string (and C++11, and obviously presuming your system uses the ASCII character set in the first place):
#include <iostream>
#include <string>
int main() {
std::string word;
std::cout << "Enter word: ";
std::cin >> word;
int ascii_total = 0;
for ( auto s : word ) {
ascii_total += s;
}
std::cout << "Sum of ASCII values of characters is: ";
std::cout << ascii_total << std::endl;
return 0;
}
This question already has answers here:
How do I iterate over the words of a string?
(84 answers)
Closed 9 years ago.
I am having problems splitting a string using pure C++
The string always looks like this
12344//1238
First int then // and then the second int.
Need help to get the two int values and ignore the //
string org = "12344//1238";
size_t p = org.find("//");
string str2 = org.substr(0,p);
string str3 = org.substr(p+2,org.size());
cout << str2 << " "<< str3;
why cant we use sscanf?
char os[20]={"12344//1238"};
int a,b;
sscanf(os,"%d//%d",a,b);
Reference
Take a look at the strtok function
This should Split and convert to integers:
#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>
class BadConversion : public std::runtime_error {
public:
BadConversion(std::string const& s)
: std::runtime_error(s)
{ }
};
inline double convertToInt(std::string const& s,
bool failIfLeftoverChars = true)
{
std::istringstream i(s);
int x;
char c;
if (!(i >> x) || (failIfLeftoverChars && i.get(c)))
throw BadConversion("convertToInt(\"" + s + "\")");
return x;
}
int main()
{
std::string pieces = "12344//1238";
unsigned pos;
pos = pieces.find("//");
std::string first = pieces.substr(0, pos);
std::string second = pieces.substr(pos + 2);
std::cout << "first: " << first << " second " << second << std::endl;
double d1 = convertToInt(first), d2 = convertToInt(second) ;
std::cout << d1 << " " << d2 << std::endl ;
}
Simplest way I can think of:
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
void main ()
{
int int1, int2;
char slash1, slash2;
//HERE IT IS:
stringstream os ("12344//1238");
os>> int1 >> slash1 >> slash2 >> int2;
//You may want to verify that slash1 and slash2 really are /'s
cout << "I just read in " << int1 << " and " << int2 << ".\n";
system ("pause");
}
Also nice because it's so easy to rewrite -- if, say, you decide to read in ints delimited by something else.
Take the integers in as a string.
The string will then have the numbers and the // symbols.
Next you can run a simple for loop looking for the '/' in the string.
The values prior to the symbol are stored in another string.
When '/' appears, the for loop will terminate. You now have the index of the first
'/' symbol.
Increment the index and copy the rest of the string using anothe for loop, in another
string.
Now you have two separate strings.
How do I get a part of a string in C++? I want to know what are the elements from 0 to i.
You want to use std::string::substr. Here's an example, shamelessly copied from http://www.cplusplus.com/reference/string/string/substr/
// string::substr
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str="We think in generalities, but we live in details.";
// quoting Alfred N. Whitehead
string str2, str3;
size_t pos;
str2 = str.substr (12,12); // "generalities"
pos = str.find("live"); // position of "live" in str
str3 = str.substr (pos); // get from "live" to the end
cout << str2 << ' ' << str3 << endl;
return 0;
}
You use substr, documented here:
#include <iostream>
#include <string>
using namespace std;
int main(void) {
string a;
cout << "Enter string (5 characters or more): ";
cin >> a;
if (a.size() < 5)
cout << "Too short" << endl;
else
cout << "First 5 chars are [" << a.substr(0,5) << "]" << endl;
return 0;
}
You can also then treat it as a C-style string (non-modifiable) by using c_str, documented here.
If the string is declared as an array of characters, you can use the following approach:
char str[20];
int i;
strcpy(str, "Your String");
// Now let's get the sub-string
cin >> i;
// Do some out-of-bounds validation here if you want..
str[i + 1] = 0;
cout << str;
If you mean std::string, use substr function as Will suggested.
Assuming you're using the C++ std::string class
you can do:
std::string::size_type start = 0;
std::string::size_type length = 1; //don't use int. Use size type for portability!
std::string myStr = "hello";
std::string sub = myStr.substr(start,length);
std::cout << sub; //should print h
use:
std::string sub_of_s(s.begin(), s.begin()+i);
which create a string sub_of_s which is the first i-th the element in s.