Reversing string in C++ - c++

In the following part of the string swap code
end = &str[len - 1];
I am not understanding the addressing part. When I do it without the addressing part it still runs but gives me a warning that "a values of type char cannot be assigned to identity of type char". Here is the full code:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char str[] = "This is a test";
char *start, *end;
int len;
int t;
cout << "Original " << str << "\n";
len = strlen(str);
start = str;
end = str[len - 1];
//this reverses the string
while (start < end) {
t = *start;
*start = *end;
*end = t;
start++;
end--;
}
cout << "Reversed" << str << "\n";
system("PAUSE");
return 0;
}

I am not understanding the addressing part.
Given
char str[] = "This is a test";
char *start, *end;
len = strlen(str);
then end is pointer to char, and
end = &str[len - 1]; // `end` points to the last character (before the `\0`)
You must use the & (address of) operator because end is pointer and so it must be assigned to the address of something (here the address of the last character of the string).
When I do it without the addressing part it still runs
I don't think it will - you should have got a compile error
end = str[len - 1]; // invalid conversion from ‘char’ to ‘char*’

You should konw the type of end is char*, but the type of str[len-1] is char, so you need change type str[n-1] to char*, so you need &str[len-1].
But if you use string, there will be an easy method:
Use the std::reverse method from STL:
std::reverse(str.begin(), str.end()); //str shoud be string type
You will have to include the "algorithm" library, #include.

Maybe this can help
void reverse (char word[])
{
int left = 0;
int right = strlen(word) - 1;
while (left < right)
{
char temp = word[left];
word[left] = word[right];
word[right] = temp;
left++;
right--;
}
cout << word;
}
I hope this gives you the idea.

Related

reverse string bus error

I'm doing some basic c++ and decided to implement a revStr method.
But for some reason every time I execute the method, I get a bus error caused by the assignments in the while loop but I can't understand why.
Anybody got any clues? Any help would be much appreciated.
char* reverseStr(char* s){
if(!s){
cout << "Void!"<<endl;
return s;
}
char* end, *start;
end = s;
start = s;
while(*(end) != '\0'){
end++;
}
end--;
while(start < end){
char temp = *start;
cout << temp <<endl;
*start = *end;
*end = temp;
start++;
end--;
}
cout << "The reversed string is: " << s <<endl;
return s;
}
Apologies.. I have added the driver program below:
int main(int argc, char** argv) {
assert(reverseChar("hello") == "olleh");
return 0;
}
If you're passing a string literal it should not compile as your func (correctly) takes non-const.
Unless, of course, you force cast it... so don't remove the const but strdup() it instead.
What could also be happening is that the loop runs forever. You can test it with a debugger.
The reason is that pointers cannot be properly compared for less, or greater then. Only for equality. You have to change your < to !=
Unable to reproduce problem ... code works as expected.
My Test (showing how I created "forwardCharStar[100]);")
int t282(void)
{
std::string forwardStr = "abcdefghijklmnopqrstuvwxyz";
size_t sz = forwardStr.size();
assert(sz < 100); // check fit
// ^^^-----------vvv
char forwardCharStar[100];
for (size_t i = sz-1; i < 100; ++i) forwardCharStar[i] = 0;
for (size_t i = 0; i < sz; ++i) forwardCharStar[i] = forwardStr[i];
std::string rS = reverseStr(forwardCharStar);
std::cout << "The reversed string is: " << rS << std::endl;
return (0);
}
Note: filled tail of forwardCharStar[100] with '\0'
- null terminator is important in c-style strings
Note: then transferred 26 chars from 'forwardStr' to front of forwardCharStar
Output:
The reversed string is: zyxwvutsrqponmlkjihgfedcba
Note: I commented out the char by char output from
2nd line of while loop
// std::cout << temp << std::endl;
Note: forwardCharStar[100] matches the reversed string, the code modifies its input string.

reverse function for a char* throwing segmentation fault

I have the following simple function:
void reverse(char* str) {
if (str == NULL)
return;
char* end = str;
while(*end != NULL) {
end++;
}
end--;
while(str < end){
char temp = *str;
*str++ = *end;
*end-- = temp;
}
}
int main(int argc, char* argv[]) {
char* second = "SOMETHING\0";
cout << "Before Reverse String: " << second << '\n';
reverse(second);
cout << "Reverse String: " << second << '\n';
}
Simple, right? however I'm getting a Segmentation Fault in lines
*str++ = *end
*end-- = temp
What am I missing?
Thanks!
You are modifying a string literal:
char* second = "SOMETHING\0";
which is undefined behavior, one solution would be to assign the literal to char array:
char second[] = "SOMETHING";
Also,string literals will be NULL terminated, so not need to add the \0. You should also modify your while loop to compare with \0 instead of NULL. Although, it should work since they both will evaluate to 0 since *end is a char it reads better to use \0:
while(*end != '\0')
Change
char* second = "SOMETHING\0";
To
char second[] = "SOMETHING";
Note: string literals are not modifiable, and you don't have to explicitly add \0 in a string literal.
while(*end != NULL) {
should be
while(*end != '\0') {
NULL is used for null pointer only.

Run time error reverse a string

I know return end is not correct, I am thinking about to use one of my pointer to go to the end, and then go back by the size of the string to return the reversed string. Is there a more efficient way of doing that? Also, more importantly, am I getting a run time error here? http://ideone.com/IzvhmW
#include <iostream>
#include <string>
using namespace std;
string Reverse(char * word)
{
char *end = word;
while(*end)
++end;
--end;
char tem;
while(word < end) {
tem = *word;
*word = *end;
*end = tem; //debug indicated the error at this line
++word;
--end;
}
return end;
}
int main(int argc, char * argv[]) {
string s = Reverse("piegh");
cout << s << endl;
return 0;
}
You're passing "piegh" to Reverse, which gets converted to a pointer to char. That pointer to char points into a read only string literal. Perhaps you meant to copy the string literal "piegh" before attempting to assign to it:
char fubar[] = "piegh";
string s = Reverse(fubar);
After all, how could you justify "piegh"[0] = "peigh"[4];?
What does this part of your code do?
while(*end)
++end; //Assuming you are moving your pointer to hold the last character but not sure y
--end; //y this one
while(word < end)// also i am not sure how this works
This code works and serves the same purpose
char* StrReverse(char* str)
{
int i, j, len;
char temp;
char *ptr=NULL;
i=j=len=temp=0;
len=strlen(str);
ptr=malloc(sizeof(char)*(len+1));
ptr=strcpy(ptr,str);
for (i=0, j=len-1; i<=j; i++, j--)
{
temp=ptr[i];
ptr[i]=ptr[j];
ptr[j]=temp;
}
return ptr;
}

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 :)

Segmentation fault error

`I am trying to write a program that reverses two strings, I though I had it done pretty well but when I run it, the program runs till line 26, then I get a segmentation fault error. The program compiles fine. I am wondering if there is a simple or obvious problem in my functions that I am not seeing, Any help would be appreciated!!
Thanks in advance
#include <iostream>
#include <string>
using namespace std;
// Reversing the characters in strings.
void reverse(string str);
void swap(char * first, char *last);
int main() {
// declarations and initialization
string str1;
string str2;
cout << "Please enter the first string of characters:\n";
cin >> str1;
cout << "Please enter the second string of characters:\n";
cin >> str2;
cout << "The strings before reversing are:" << endl;
cout << str1 << " " << str2 << endl;
// reverse str1
reverse(str1);
// reverse str2
reverse(str2);
// output
cout << "The strings after reversing: " << endl;
cout << str1 << " " << str2 << endl;
return 0;
}
void reverse(string str) {
int length = str.size();
char *first = NULL;
char *last = NULL;
first = &str[0];
last = &str[length - 1];
for (int i = 0; first < last; i++) {
swap(first, last);
first++;
last--;
}
}
void swap(char *first, char *last) {
char * temp;
*temp = *first;
*first = *last;
*last = *temp;
}
I don't know where line 26 is, but
char * temp;
*temp = ...
is not valid. temp should be pointed at a char, or (better yet) rewrite the function to where temp is a char.
Seth Carnegie observes that you'll have to pass the strings by reference if you want to modify the originals.
void reverse(string& str) { //pass by reference, so origional is modified
In your swap function, you are assigning a value to *temp when temp is not pointing to anything (it's uninitialized). Thus, your segmentation fault.
You want this:
void swap(char* first, char* last)
{
char temp = *first;
*first = *last;
*last = temp;
}
The other answers are valid in regards to the segfault cause.
I just think you may be interested in knowing that you can reverse a string easily using std::string's reverse_iterator:
std::string reverse(std::string str) {
std::string out;
for (std::string::reverse_iterator it = str.rbegin(); it != str.rend(); it++) {
out += *it;
}
return out;
}
So, calling:
reverse("foo");
...will return oof.
You're passing the strings by value, which means only a local copy of the string will be reversed in the reverse function. You should pass them by reference.
Also, don't alter the string's memory directly. Use operator[] like this:
for (size_t beg = 0, size_t end = str.size() - 1; beg < end; ++beg, --end)
str[beg] = str[end];
So all together:
void reverse(string& str); // prototype
....
void reverse(string& str) { // note the & which is pass by reference
int length = str.size();
for (size_t beg = 0, size_t end = str.size() - 1; beg < end; ++beg, --end)
str[beg] = str[end];
}
And as stated by Mooing Duck, the place you're probably crashing from is dereferencing a pointer which has a garbage value here:
char * temp;
*temp = ...
You're trying to assign some random memory a value, which is probably segfaulting you.
Again, others have pointed out the what the problem is and would like to show you this:
void reverse(std::string & str) {
for (int i = 0, last = str.size() - 1, lim = str.size() / 2 ; i < lim;) {
std::swap(str[i++], str[last--]);
}
}
I have not tested it thoroughly though.