Reverse string code using passing by reference method not working - c++

Please tell me why my code to reverse the input string is giving me various errors.
#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;
void ReverseString(string &aString);
int main(){
string info;
cout << "What's your string?" << endl;
getline(cin, info);
ReverseString(info);
cout << ReverseString(string info) << " compare with: " << info << endl;
system("pause");
return 0;
}
void ReverseString(string &aString){
for(int i = 0; i < aString.length(); i++)
{
string temp = 0; // initialize temporary string
temp = temp + aString.at(aString.length() - 1 - i); // hold temporary string
if(i => aString.length()) /*assign temp string to aString when all chars are processed*/
{
temp = &aString;
}
}
}

Hi you could simplify your code a lot by using the STL
for example:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
std::string str = "Hello World";
cout << str << endl;
std::reverse(str.begin() , str.end());
cout << str << endl;
return 0;
}
let me know if this is not suitable to your needs as theres a few other ways to do it too.
Without STL:
There are some corrections/changes to your code required, which I have supplied below. However you may want to look at some documentation on referencing variables to get an idea of how it works, such as:
http://www.cprogramming.com/tutorial/references.html
http://www.thegeekstuff.com/2013/05/cpp-reference-variable/
http://en.wikipedia.org/wiki/Reference_(C++)
What is a reference variable in C++?
http://www.tutorialspoint.com/cplusplus/cpp_references.htm
Correct reference and pointer use is a major part of C++ and allows for some of the most powerful functionality in the language, provided it is used correctly, or major headaches and mental scarring if used incorrectly, so it is worth, even essential, to have a firm grasp of them.
And even then expect the odd misuse to crop up every-so-often. :)
#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;
void ReverseString(string &aString);
int main(){
string info;
cout << "What's your string?" << endl;
getline(cin, info);
cout << info << " compare with: ";
ReverseString(info);
cout << info << endl;
system("pause");
return 0;
}
void ReverseString(string &aString)
{
int len = aString.length();
string temp = aString;// initialize temporary string
aString ="";
for(int i = 0; i < len; i++)
{
aString += temp[len - (1+ i)]; // assigns the reversed value to the referenced string
}
}
Just noticed the quote below from #zac-howland : so true, I have however left the code in as an illustrative piece. Provided some reading is done on this as well as plenty of experimentation I hope NewProgrammer will get the information and skill-set he needs to go forward.

#include<iostream>
#include<string>
#include <algorithm>
using namespace std;
string info;
string rvrs(string &str)
{
std::reverse(str.begin(),str.end());
return str;
}
int main()
{
cout<<"What is your string :: ";
getline(cin,info);
cout<<rvrs(info);
cout<<endl;
return 0;
}

You have a few syntactical errors in addition to your logical ones:
cout << ReverseString(string info) << " compare with: " << info << endl;
ReverseString(string info) will pass in an empty string to your ReverseString function (if it even compiles - which looks like it should not since you have 2 info's in the same scope). What you wanted is:
cout << ReverseString(info) << " compare with: " << info << endl;
In your reverse function, you only need to go to length() / 2.
Since you are passing by reference, changes you make to the string within the function will be reflected in the object you passed into it. That is, the original info will be reversed. If you want it to operate on a copy, you need to pass it by copy, not by reference.
Finally, cout << ReverseString(info) is not useful (if it even compiles) as ReverseString returns a void. You should have it return a string (the reversed string).

You have a number of problems.
string temp = 0; // initialize temporary string
It doesn't really make sense to initialize a string to 0. Just string temp; would be fine here.
temp = temp + aString.at(aString.length() - 1 - i); // hold temporary string
That's not quite how I'd do things, but I guess it should work.
if(i => aString.length())
This condition doesn't seem to make sense. Your loop is defined to iterate with i going from 0 to the length of the string -1, so it can never be greater than or equal to the string length.
/*assign temp string to aString when all chars are processed*/
{
temp = &aString;
}
Here the code doesn't match the comment. The comment says you're going to assign to aString, but the code assigns something to temp. The comment is probably closer to what you really want. But you still need to fix the condition, and probably want to do this after the loop has finished executing. So in pseudo-code, you'd end up with something like:
for (all characters in the string)
add the next character in the string to the end of temp
assign temp back to the original string

Related

reverse array using recursion in c++

The assignment is relatively simple reverse the array in main using the ReverseStringRecursive function. However the limitation is I can only use a single int and a char nothing else that declares a variable (this includes the banning of for loops and so on). Additionally no extra libraries may be used I am limited to iostream and conio.h. The problem I'm having is that the string will be printed forward and then backwards when I just need it to be printed backwards. the reverseMe variable is pointing to a string in main that contains "abcdefghijklmnopqrstuvwxyz". This function is not suppose to print the string just reverse is then main will print the string.
// INCLUES AND NAMESPACES
#include <iostream>
#include<conio.h>
using namespace std;
// CONSTANTS
const int STRING_SIZE = 100;
// PROTOTYPES
int ReverseStringRecursive(char*);
// MAIN
int main() {
// create a string
char someString[STRING_SIZE] = "abcdefghijklmnopqrstuvwxyz";
// display the string before being reversed
cout << "The string contains: " << endl;
cout << someString << endl << endl;
// make the call to the recursive function
cout << "CALL THE REVERSING FUNCTION" << endl << endl;
ReverseStringRecursive(someString);
// display the string after being reversed
cout << "The string contains: " << endl;
cout << someString << endl;
// exit program
_getch();
return 0;
}
int ReverseStringRecursive(char* reverseMe) {
// YOUR IMPLEMENTATION GOES HERE...
int position = 0;
char holder = ' ';
if (reverseMe[0] == '\0') {
return 1;
}
else {
holder = reverseMe[position];
}
ReverseStringRecursive(reverseMe + 1);
while (reverseMe[position] != '\0') {
position++;
}
reverseMe[position] = holder;
return position;
}
Example output that I am getting:
"abcdefghijklmnopqrstuvwxyz zyxwvutsrqponmlkjihgfedcba"
what I'm suppose to get:
"zyxwvutsrqponmlkjihgfedcba"
Tough problem. You have to shorten the inner string on each recursion by placing a '\0' on the last character before calling the recursive function and then performing the swap after the recursive call.
algorithm:
0. save the index of the last character in the string
1. Save the last character of the current string
2. Set the last character of the current string to null (use the saved index)
3. Call the recursive function starting one character in which will recurse the algorithm for the next inner string (we have already shortened the end of the recursed string)
4. Once the recursion has finished, set the last character to the first char of the current string; then
5. set the first character of the current string to the saved character (which was at the end)
This will work for odd-length strings as well.
The following code should work on a windows system. To make it work on Linux, simply comment out the conio.h include line, comment the __getch() line and uncomment the cin.getch() line.
// INCLUES AND NAMESPACES
#include <iostream>
#include <conio.h>
using namespace std;
// CONSTANTS
const int STRING_SIZE = 100;
// PROTOTYPES
int ReverseStringRecursive(char *);
char *orig;
// MAIN
int main()
{
// create a string
char someString[STRING_SIZE] = "abcdefghijklmnopqrstuvwxyz";
orig = someString;
// display the string before being reversed
cout << "The string contains: " << endl;
cout << someString << endl << endl;
// make the call to the recursive function
cout << "CALL THE REVERSING FUNCTION" << endl << endl;
ReverseStringRecursive(someString);
// display the string after being reversed
cout << "The string contains: " << endl;
cout << someString << endl;
// exit program
_getch(); // uncoment conio.h on a windows system
// std::cin.get(); // use this if on a linux system
return 0;
}
int ReverseStringRecursive(char *reverseMe)
{
int last_index = 0;
while (reverseMe[last_index + 1] != '\0')
last_index++;
char save_char = reverseMe[last_index];
if (*reverseMe != '\0') {
reverseMe[last_index] = '\0'; // shorten the inner string by one
// recurse on the shorter string
ReverseStringRecursive(reverseMe + 1);
// save the outer two characters
reverseMe[last_index] = *reverseMe;
*reverseMe = save_char;
}
}
You are overwriting your terminating '\0' and therefore corrupting your string. When your while loop exists, reverseMe[position] is at '\0' and then you overwrite it with the value holder. Your string is no longer null-terminated and you are getting undefined behavior on your next while loop as it accesses outside the bounds of your array.

C++ reversing a string

I'm trying to reverse a string in my C++ code line below revStr.at(j) = str.at(size);
But it doesn't change any of the elements in revStr.
Is there another way to do it without using any libraries.
#include <iostream>
#include<sstream>
#include <iterator>
using namespace std;
int main() {
ostringstream d;
long long c = 123456789;
d << c;
//cout << c << endl;
string str = d.str();
//cout << str.at(0) << endl;
int size = str.size() - 1;
//cout << size << endl;
ostringstream e;
e << str;
string revStr = e.str();
for (int i = size; size==0; size--) {
//cout << str.at(size);
int j = 0;
revStr.at(j) = str.at(size);
j++;
} // End For
cout << "Original String is :" << str << endl;
cout << "Reversed String is :" << revStr << endl;
}
Use std::reverse:
#include <string>
#include <algorithm>
#include <iostream>
int main()
{
std::string test{"Hello"};
std::cout << "Original string: " << test << std::endl;
std::reverse(test.begin(), test.end());
std::cout << "Reversed string: " << test << std::endl;
return 0;
}
Output:
Original string: Hello
Reversed string: olleH
If you just want to reverse a string, you should use std::reverse, as described by Tyler Lewis. It is the best option.
If you want to learn C++, then writing your own version is good practice.
The line
for (int i = size; size==0; size--)
means “Create a new int called i and set it to size initially. Then, while size is zero, do the following and then decrement size”.
There are three problems with this:
Size is not zero unless you entered a one-character string
Since you never use i, there’s no point in declaring it
Inside the loop you use j which is set to zero each time.
You can fix the first by changing the middle part of the for loop to size >= 0 (but be careful—if you later change it so that size is an unsigned type, because it doesn’t make sense for it to be negative, that code won’t work; it’s generally better to increment going up instead). You can fix the second by using i everywhere in the loop statement, and not changing size. You can fix the third by using i in the loop body, and not declaring a new variable inside the loop.
I noticed you used std::string so I used std function swap and string. Depending on if you consider this as a 'library'. There are several definitions of 'reverse'. You could reverse the word order in a string, or a pure char to char reversal like I wrote. Reversal could also mean changing character case, etc... but this is simply swap first and last. Then swap the 2nd and 2nd to last, then swap the 3rd and 3rd to last, etc...
So some points from your code. You only need to loop half the string length. The swap is from the ith and the ith to last. So the last is numCharacters - 1, thus the ith to last would be Last - i or numCharacters - 1 - i. I believe this is what you intended by using a farLeft(i) and a farRight(j) index.
#include <iostream>
void reverseStringInPlace(std::string &stringToReverse)
{
int numCharacters = stringToReverse.length();
for (int i=0; i<numCharacters/2; i++)
{ std::swap(stringToReverse[i], stringToReverse[numCharacters-i-1]); }
}
int main()
{
std::string stringToReverse = "reversing a string";
std::cout << stringToReverse << std::endl;
reverseStringInPlace(stringToReverse);
std::cout << stringToReverse << std::endl;
return 0;
}
Output:
reversing a string
gnirts a gnisrever
Changes made to the piece of code in question, it works.
for (unsigned int i = size; size >= 0; size--) {
revStr[j] = str[size];
j++;
}

'Replace' a char with an int in a string

At first this seemed easy to do but I was mistaken. I want to 'replace' a char (a variable) in a string with a int (value). But how?
I tried replace() because I'm working with a string and it worked but it will not work if I wish to change the value of the variable again to another
value because then the original variable will not be found. I have been struggling with this for the passed 2 days. Any help will be much appreciated on how to do this.
changeVar(string startingExpr, char var, int val)
{
for(int i = 0; i < startingExpr.length(); i++)
{
if(startingExpr[i] == var)
{
cout << "I found x! Now to replace it!";
startingExpr[i] = val; //'Replace' x with 5, but x but how?
}
}
}
Your help on this one will be much appreciated.
J
If you want to be able to replace the "variable" by the "value" as many times as you want, you should keep a copy of the original string and do the replacement from there only.
Another option is to undo the replacement (replace the value by the variable) and redo with another value, provided the undo can be done unambiguously.
I am sorry to hear this problem wasted your more than 2 days. You shouldcarefully read a basic C++ textbook. As your problem is a very basic one. If you understand the arguments passing for function, you will sort this out!
More specific, you function is not wrong, but just did not deliver the results you want. Because your function using argument, which will make a copy of argument startingExpr inside the function body, when you make replacement using "startingExpr[i] = val", the replacement is happened on the copy of startingExpr (which is a local variable just visible inside the function), your original startingExpr does change at all.
The solution is very simple, change argument passing with its reference, just add &, now the declaration your function should be: "changeVar(string startingExpr, char var, int val)"
Try the following code, which will demonstrate my explanation:
#include <iostream>
#include <string>
using namespace std;
//the original function which was reported had problem
// This because the function using parameter not reference
void changeVar(string startingExpr, char var, int val)
{
for(int i = 0; i < startingExpr.length(); i++)
{
if(startingExpr[i] == var)
{
cout << "I found x! Now to replace it!(But the replace is happend inside the function, the original string is not changed!)"<<endl;
startingExpr[i] = val; //'Replace' x with 5, but x but how?
}
}
}
// updating using the reference
//void changeVar(string & startingExpr, char var, int val)
void changeVar_refe(string & startingExpr, char var, int val)
{
for(int i = 0; i < startingExpr.length(); i++)
{
if(startingExpr[i] == var)
{
cout << "I found x! Now to replace it!(Now using reference, the replace is happend inside the original string, which will be changed!)"<<endl;
startingExpr[i] = val; //'Replace' x with 5, but x but how?
}
}
}
int main()
{
//lets test the original function
string my_name="Hi there, I am C++ taoism .";
cout<<"The original string is: "<<my_name<<endl;
//lets change a to A
changeVar(my_name,'a',65);
cout<<"The changed string is: "<<my_name<<endl;
cout<<endl;
cout<<"Using the reference to test ... "<<endl;
cout<<endl;
cout<<"The original string is: "<<my_name<<endl;
//lets change a to A
changeVar_refe(my_name,'a',65);
cout<<"The changed string is: "<<my_name<<endl;
//cout <<"Char A is int 65:"<<int('A')<<endl;
}
Your mistake is to assign the number that is different from the ASCII character represntation. In ASCII table characters '0', '1' .. '9' goes one after another. So you can rewrite your code as:
startingExpr[i] = '0' + val;
But please aware that this is good for one character case only. If you need to replace multiple chars then your solution without need for a function is that:
#include <iostream>
#include <string>
int
main()
{
std::string a("SomeVar1"), b("SomeVar356");
std::string::size_type index = std::string::npos;
std::cout << "Before: " << a << std::endl;
if ((index = a.rfind("1")) != std::string::npos)
a.replace(index, 1, std::to_string(2));
std::cout << "After: " << a << std::endl;
std::cout << "Before: " << b << std::endl;
if ((index = b.rfind("356")) != std::string::npos)
b.replace(index, 3, std::to_string(673));
std::cout << "After: " << b << std::endl;
return 0;
}
This is slightly optimized since it is using rfind (search from the end of the string).
P.S. As the comments suggested - you can use std::replace with reverse iterators and lambda for condition. Since it is available in C++11 I wrote a small example in universal style.

How to print this manually made string

I just needed to reverse a string, so I declared a new string variable and iteratively copied the elements. Now i want to print the reversed string through cout << reversed; but this is printing nothing. I can print it through a for loop through reverse[i] until the size but is there any better way?
#include <iostream>
#include <string>
using namespace std;
int main()
{
string original = "hello";
string reverse;
int i, j = 0, size = original.length();
for (i = size - 1; i >= 0; i--) // original's last as reversed's first
{
reverse[j] = original[i];
j++;
}
reverse[j] = '\0'; //last value as null
cout << "original string = " << original << endl;
cout << "reversed string = " << reverse << endl;
system("pause");
return 0;
}
A better solution is to use std::reverse:
std::string original = "whatever";
std::string rev = original;
std::reverse(rev.begin(), rev.end());
You can use reverse iterators to instantiate the reversed string from the original:
string original = "hello";
string reverse(original.rbegin(), original.rend());
Then
std::cout << "reversed string = " << reverse << std::endl;
Note: avoid using namespace std;. There is an algorithm called std::reverse, whose name you could be inadvertently pulling into the global namespace. And you do have a variable with that name.
See this working demo.
The major problem with your code is that reverse is empty, so using any index leads to you indexing out of bounds and undefined behavior.
As a side-note, you don't have to terminate std::string objects, they are automatically terminated.
you should notice that string reverse doesn't have a size , so when you do something like this
for (i = size - 1; i >= 0; i--) // original's last as reversed's first
{
reverse[j] = original[i];
j++;
}
Here, you are accessing an index that is not found in string reverse,as it's size is 0 . You should take care of something like that.
There are plenty of answers that your received about this question , I just wanted to make you notice this mistake
instead , you can make
reverse+=original[i];
You don't even need to create a new string to hold the reversed string. Just iterator over the original string.
void print_reversed(const std::string& str)
{
std::copy(str.crbegin(), str.crend(), std::ostream_iterator<char>(std::cout));
}

passing array as parameter to a function

this script is supposed to output array values that were inputted by the user into array "store." I am trying to store all the char array values into string temp. I get the error on line 12: "[Error] invalid conversion from 'char*' to 'char' [-fpermissive]." Would appreciate any help!
Edit: so I fixed the declaration and now at least it compiles, but the answer I get on my cmd is all jumbled up. Why is this so? The cmd only correctly couts the first string but after the space, it messes up.
#include <iostream>
#include <cstdlib>
using namespace std;
void coutArray(char[], int);
int main()
{
char store[50];
cout << "enter text: " << endl;
cin >> store;
coutArray(store, 50);
system("pause");
return 0;
}
void coutArray(char store[], int max)
{
string temp = "";
int i = 0;
while (i < max)
{
temp += store[i];
i++;
}
cout << temp << endl;
}
Using input from all answerers I finally got the fixed code:
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
void coutArray(char[], int);
int main()
{
char store[50] = {0};
cout << "enter text: " << endl;
cin.getline(store, 50);
coutArray(store, 50);
system("pause");
return 0;
}
void coutArray(char store[], int max)
{
string temp = "";
int i = 0;
while (i < max && store[i]!=0)
{
temp += store[i];
i++;
}
cout << temp << endl;
}
Thanks everyone. i learned a lot!!!
When you get an input using "cin" your input automatically ends with 0 (NULL).
You just need to add one little piece of code to your while statement.
instead of this :
while (i < max)
use this :
while (i < max && store[i]!=0)
Now it will stop when the input string is finished and won't print any garbage existed in the array beforehand.
To show that cin does add terminating zero, i initialized the array to 46, and put a breakpoint after the cin
so I fixed the declaration and now at least it compiles, but the answer I get on my cmd is all jumbled up. Why is this so?
Not sure what you mean by jumbled up. But since you did not tell us what you typed its hard to know it looks like it worked to me:
> ./a.out
enter text:
Plop
Plop�ȏU�
Notice that since my input is only 4 characters long. This means that a lot of the characters in the array still have undefined (ie random values). This is why I am seeing junk. To get past this initialize the array to have all 0 values.
char store[50] = {0};
Even bettern use a C++ object than handles longer strings.
std::string store;
std::getline(std::cin, store);
Note: passing arrays to functions by value is not a good idea. On the other end they have decayed to pointers and thus do not act like arrays anymore (they act like pointers whose semantics are similar but not identical).
If you must pass an array pass it by reference. But I would use a C++ container and pass that by reference (it is much safer than using C constructs). Have a look at std::string
The declaration of the function is wrong. Should be void coutArray(char *, int);
Look at the Implicit Conversion rules to understand what the compiler can do and what it cannot to do for you.
The issue with your program was that you were probably entering in less characters than the maximum size of the buffer. Then when you passed the maximum size as the parameter to coutArray, you assigned unfilled slots in the char array to temp. These unfilled slots could contain anything, as you have not filled them up to that point.
Your program is still correct, but what would be better would be to use read so that the number of bytes you specify is the minimum number of bytes that can be entered:
std::cin.read(store, 50);
Even better solution would be to use std::string:
std::string store;
std::cin >> store;
// or for the entire line
std::getline(std::cin, store);
It also follows that your coutArray should be changed to:
void coutArray(std::string);
// ...
void coutArray(std::string str)
{
std::cout << str << std::endl;
}
Look at this way
template<typename T, size_t N>
void MyMethod(T (&myArray)[N])
{
//N is number of elements, myArray is the array
std::cout<<"array elements number = "<<N<<endl;
//put your code
string temp;
temp.resize(N+1);//this is for performance not to copy it each time you use += operator
int i = 0;
while (i < max)
{
temp += store[i];
i++;
}
cout << temp << endl;
}
//call it like this
char arr[] = "hello world";
MyMethod(arr);