newbie question

B

BrianJones

Having programmed in java for many years, I decided to try C++ for speed...
Anyway, am writing this simple encryption program, and a method I have takes
an array of chars (i.e. bytes) and swaps the two halves around e.g:

0,1,2,3,4,5,6,7,8 -> 5,6,7,8,4,0,1,2,3

But - it doesn't work properly and I can't see the problem? Any suggestions?
The following is the method:

char* swap(char* bytes)
{ long pivot;
char *swappedBytes;
bool parity = false; // whether length odd or even
swappedBytes = new char[strlen(bytes)-1];
if(strlen(bytes)%2==0)
{
pivot = strlen(bytes)/2;
parity = false; // even
}
else
strlen(bytes)%2==1){
pivot = ((strlen(bytes)-1)/2);
parity = true; // odd
}
if(parity)//odd
{
for(int i = 0;i<pivot;i++){
swappedBytes = bytes[i+pivot+1];
}
for(int i = pivot+1;i<strlen(bytes);i++){
swappedBytes = bytes[i-pivot-1];
}
swappedBytes[pivot] = bytes[pivot];
}
else if(!parity)//even
{
for(int i=0;i<pivot;i++){
swappedBytes = bytes[i+pivot];
}
for(int i = pivot;i<strlen(bytes);i++){
swappedBytes = bytes[i-pivot];
}
}
return swappedBytes;
}

Thanks,
Ben
 
J

John Harrison

Having programmed in java for many years, I decided to try C++ for
speed...
Anyway, am writing this simple encryption program, and a method I have
takes
an array of chars (i.e. bytes) and swaps the two halves around e.g:

0,1,2,3,4,5,6,7,8 -> 5,6,7,8,4,0,1,2,3

But - it doesn't work properly and I can't see the problem? Any
suggestions?
The following is the method:

char* swap(char* bytes)
{ long pivot;
char *swappedBytes;
bool parity = false; // whether length odd or even
swappedBytes = new char[strlen(bytes)-1];
if(strlen(bytes)%2==0)
{
pivot = strlen(bytes)/2;
parity = false; // even
}
else
strlen(bytes)%2==1){
pivot = ((strlen(bytes)-1)/2);
parity = true; // odd
}
if(parity)//odd
{
for(int i = 0;i<pivot;i++){
swappedBytes = bytes[i+pivot+1];
}
for(int i = pivot+1;i<strlen(bytes);i++){
swappedBytes = bytes[i-pivot-1];
}
swappedBytes[pivot] = bytes[pivot];
}
else if(!parity)//even
{
for(int i=0;i<pivot;i++){
swappedBytes = bytes[i+pivot];
}
for(int i = pivot;i<strlen(bytes);i++){
swappedBytes = bytes[i-pivot];
}
}
return swappedBytes;
}

Thanks,
Ben


One problem is that you are accessing one past the end of your allocated
array

swappedBytes = new char[strlen(bytes)-1];

for(int i = pivot+1;i<strlen(bytes);i++){
swappedBytes = bytes[i-pivot-1];

john
 
B

BrianJones

John Harrison said:
Having programmed in java for many years, I decided to try C++ for
speed...
Anyway, am writing this simple encryption program, and a method I have
takes
an array of chars (i.e. bytes) and swaps the two halves around e.g:

0,1,2,3,4,5,6,7,8 -> 5,6,7,8,4,0,1,2,3

But - it doesn't work properly and I can't see the problem? Any
suggestions?
The following is the method:

char* swap(char* bytes)
{ long pivot;
char *swappedBytes;
bool parity = false; // whether length odd or even
swappedBytes = new char[strlen(bytes)-1];
if(strlen(bytes)%2==0)
{
pivot = strlen(bytes)/2;
parity = false; // even
}
else
strlen(bytes)%2==1){
pivot = ((strlen(bytes)-1)/2);
parity = true; // odd
}
if(parity)//odd
{
for(int i = 0;i<pivot;i++){
swappedBytes = bytes[i+pivot+1];
}
for(int i = pivot+1;i<strlen(bytes);i++){
swappedBytes = bytes[i-pivot-1];
}
swappedBytes[pivot] = bytes[pivot];
}
else if(!parity)//even
{
for(int i=0;i<pivot;i++){
swappedBytes = bytes[i+pivot];
}
for(int i = pivot;i<strlen(bytes);i++){
swappedBytes = bytes[i-pivot];
}
}
return swappedBytes;
}

Thanks,
Ben


One problem is that you are accessing one past the end of your allocated
array

swappedBytes = new char[strlen(bytes)-1];

for(int i = pivot+1;i<strlen(bytes);i++){
swappedBytes = bytes[i-pivot-1];

john


Surely such is not the case, since the i iterator (according to the for
loop) is only allowed to go up to <strlen(bytes) i.e. strlen(bytes)-1 which
is the amount of space allocated for array swappedBytes, so there shouldn;t
be any problems?

Ben
 
J

John Harrison

One problem is that you are accessing one past the end of your allocated
array

swappedBytes = new char[strlen(bytes)-1];

for(int i = pivot+1;i<strlen(bytes);i++){
swappedBytes = bytes[i-pivot-1];

john


Surely such is not the case, since the i iterator (according to the for
loop) is only allowed to go up to <strlen(bytes) i.e. strlen(bytes)-1
which
is the amount of space allocated for array swappedBytes, so there
shouldn;t
be any problems?


If i == strlen(bytes) - 1 and the array is size strlen(bytes) - 1, then
you have accessed one past the end of the array.

For instance

int a[10];
a[10] = 0; //error!!!

It's exactly the same in Java.

john
 
J

Juha Kettunen

BrianJones said:
Having programmed in java for many years, I decided to try C++ for speed...
Anyway, am writing this simple encryption program, and a method I have takes
an array of chars (i.e. bytes) and swaps the two halves around e.g:

0,1,2,3,4,5,6,7,8 -> 5,6,7,8,4,0,1,2,3

do you rather mean:

0,1,2,3,4,5,6,7,8 -> 5,6,7,8,0,1,2,3,4

why is 4 in the middle?
 
J

Juha Kettunen

Juha Kettunen said:
do you rather mean:

0,1,2,3,4,5,6,7,8 -> 5,6,7,8,0,1,2,3,4

why is 4 in the middle?


oh, sorry, i just understood,,, only four numbers are swapped ..
 
I

Ivan Vecerina

BrianJones said:
Having programmed in java for many years, I decided to try C++ for speed...
Anyway, am writing this simple encryption program, and a method I have takes
an array of chars (i.e. bytes) and swaps the two halves around e.g:

0,1,2,3,4,5,6,7,8 -> 5,6,7,8,4,0,1,2,3

But - it doesn't work properly and I can't see the problem?
[others have answered this already]
Any suggestions?

First of all, if your focus is on performance, you should understand
the performance of standard library functions and avoid unnecessary
pessimizations. For example, calling strlen() multiple times in your
code will imply a performance penalty. Also, it might be best to
avoid memory allocations: the data can be swapped in-place.
A 'performance-oriented' version of the function may look like:

#include <algorithm>
#include <cstring>
using namespace std;

// modifies the contentes of 0-terminated 'buf' as described above
void swapHalves(char* buf)
{
size_t const len = strlen(buf);
swap_ranges( buf, buf+len/2, buf+(len+1)/2 );
}


But as a newbie, I would start by taking advantage of standard
C++ classes such as std::string :

#include <string>
using namespace std;

// modifies the contentes of 0-terminated 'buf' as described above
string swapHalves(const string& src)
{
size_t const len = src.size();
string ans;
ans.reserve(len); // optional, may avoid memory reallocations

ans.append( src.end()-len/2, src.end() ); // start with 2nd half
if( 0!=len%2 )
ans.push_back( src[len/2] ); // appends a single character
ans.append( src.begin(), src.begin()+len/2 ); // append 1st half
return ans;
}


hth,
Ivan
 
I

Ivan Vecerina

BrianJones said:
Having programmed in java for many years, I decided to try C++ for speed...
Anyway, am writing this simple encryption program, and a method I have takes
an array of chars (i.e. bytes) and swaps the two halves around e.g: ....
But - it doesn't work properly and I can't see the problem? Any suggestions?
The following is the method:

One additional point/clarification that others have not explained:
your probram uses C-style strings, which are assumed to
be terminated with a byte whose value is zero.
This zero-end mark is required by string-related C library functions,
such as strlen. strlen has to scan the string to find the first zero-value,
from which it computes the length of the string.
This means that:
- a byte value of 0 ( not '0' ) in your source string will be
interpreted as an end-of-string signal.
- in your output, you'll probably also want to copy
the zero-termination marker -- and to allocate it as well.
- calling strlen can be slow (it takes linear time, not constant time).

All these problems disappear if you use the C++ std::string class instead
of character arrays -- as in the second example I previously posted.

hth,
Ivan
 
R

Robbie Hatley

BrianJones said:
Having programmed in java for many years, I decided to try C++ for speed...
Anyway, am writing this simple encryption program, and a method I have takes
an array of chars (i.e. bytes) and swaps the two halves around e.g:
0,1,2,3,4,5,6,7,8 -> 5,6,7,8,4,0,1,2,3

I take it you meant:
0,1,2,3,4,5,6,7 -> 4,5,6,7,0,1,2,3

Otherwise, how are you going to take "half" of
nine numbers? The ninth number doesn't split
very well. :)

Also, I believe you meant for the "4" to be
at the beginning of the swapped string?

I'd use std::list and list.splice();
it makes this kind of thing a breeze:

#include <iostream>
#include <list>

int main()
{
// Make and load your list:
std::list<char> List;
for (char i = 0; i<8; ++i)
List.push_back(i);

// Get an iterator to fifth element:
std::list<char>::iterator i;
i = find(List.begin(), List.end(), 4);

// Splice fifth-through-eighth elements to beginning:
List.splice(List.begin(), List, i, List.end());

// Print results and return:
for (i = List.begin(); i != List.end(); ++i)
std::cout << static_cast<int>(*i) << " ";
std::cout << std::endl;
return 0;
}

--
Cheers,
Robbie Hatley
Tustin, CA, USA
email: lonewolfintj at pacbell dot net
web: home dot pacbell dot net slant earnur slant
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top