Reputation: 3772
I have the following code in c# which reverses a string:
char[] charArray = s.ToCharArray();
int len = s.Length - 1;
for (int i = 0; i < len; i++, len--)
{
charArray[i] ^= charArray[len];
charArray[len] ^= charArray[i];
charArray[i] ^= charArray[len];
}
return new string(charArray);
I am trying to convert it to C++ as an intellectual exercise more than anything. Here is what I have so far:
void main(void)
{
char* str = "testing";
char* result;
int len;
len = strlen(str);
if (len <= 12)
{
result = new char[strlen(str)];
for (int i = 0; i < len; i++, len--)
{
result[i] ^= str[len];
result[len] ^= str[i];
result[i] ^= str[len];
}
}
else{
std::reverse(str, &str[strlen(str)]);
}
cout << endl << result << endl;
// cleanup
str = NULL;
result = NULL;
}
In .Net if the string is <= 12 (I think it's twelve) xor is faster than array reverse. Source - Sam Saffron I am basically trying to see if it still holds up in C++.
The string comes out in a weird format (════╣¥¿ë²²² to be precise).
Any ideas?
Note: I know the else statement doesn't work, I'll figure that bit out after ;)
Note 2: I am probably doing this completely wrong, so feel free to point absolutely anything out
Update
Thanks to everyone that has participated. I haven't played with c++ in a fair few years (and it shows) and thought it would be quiet easy to convert but obviously not. Think it's best I abandon this idea. Thanks again
Upvotes: 0
Views: 343
Reputation: 53017
xor swap is for swapping. If you're copying into a result
array then that's assigning, not swapping. Also, you must only iterate half-way through the array, otherwise you swap it twice.
Here is a translation of the C# code:
#include <iostream>
#include <algorithm>
int main(void)
{
char str[] = "testing"; // arrays have automatic storage - no need to new/delete
const size_t str_len = sizeof(str)-1; // sizeof(str) returns size of the array
if (str_len <= 12) // because str_len is a constant expression, the other branch will be compiled-out
{
// this should probably use iterators (pointers) but oh well
for (size_t i = 0, len = str_len-1; i < str_len/2; i++, len--)
{
str[i] ^= str[len];
str[len] ^= str[i];
str[i] ^= str[len];
}
}
else{
std::reverse(str, str + str_len); // str decays to a pointer
}
std::cout << str << '\n'; // don't use endl if you don't need to flush
}
This is pretty bad code. Just use std::string
and std::reverse
. It is faster than xor and only 2 lines long.
std::string str = "testing"
std::reverse(str.begin(), str.end());
Upvotes: 2
Reputation: 75130
A few things:
result = new char[strlen(str)];
Should be
result = new char[len + 1];
len
because you've already calculated the length of str
, and + 1
to make room for the NUL terminator.
Secondly, you need to copy the string into result
before operating on it, because otherwise your array is full of garbage otherwise:
strcpy(result, str);
Thirdly,
std::reverse(str, &str[strlen(str)]);
Is wrong for two reasons: one, because you can't modify string literals, and two, because you should be using result
:
std::reverse(result, result + len);
But if you do that, you also need to copy str
into result
first.
And lastly, setting a pointer to NULL
does not deallocate the memory it points to. You have to
delete[] result; // delete[] because new[]
Note that for this to work even when the else
is taken (and therefore result
is not made to point to allocated memory), you need to do
char* result = NULL; // delete[] is defined as a nop on NULL pointers
All the above applies if you're sure you want to use C-strings. Once you get the hang of pointers, you can graduate to std::string
:
std::string str("testing");
std::reverse(std::begin(str), std::end(str)); // or if you don't want to do it in-place,
// std::string result(str.rbegin(), str.rend());
Upvotes: 2
Reputation: 63190
A better way of doing it, more C++, less C
std::string mystring = "testing";
std::string reversed;
for(std::string::iterator str_it = mystring.rbegin(); str_it != mystring.rend(); ++str_it)
{
reversed += *str_it;
}
std::cout << reversed << std::endl;
Upvotes: 1