Re: no-fail swap for char []'s
Dennis Jones wrote:
"Alf P. Steinbach" <alfps@start.no> wrote in message
news:13oteknga4lvu80@corp.supernews.com...
Well, after thinking about it for a few minutes, I came up with this:
void strswap( char * const c1, char * const c2 )
{
int size = std::max( strlen(c1), strlen(c2) ) + 1;
for ( int c=0; c<size; ++c )
{
std::swap( c1[c], c2[c] );
}
}
The questions you posed looked like homework.
Hi Alf, I was hoping you or Victor would respond!
No. I am a professional, though I do work from home, so I guess you *could*
call it homework! But it is NOT schoolwork. The example code I provided is
just to demonstrate what I would like to do in an existing application to
improve the reliability of the existing code and the strswap() function
therein (which is awful):
void strswap( char * const c1, char * const c2 )
{
char *temp = strdup( c1 );
strcpy( c1, c2 );
strcpy( c2, temp );
free( temp );
}
the std::swap in algorithm requires the type to be Assignable,
so with /char*/, you can simply use std::swap.
while array is not Assignable, so you have to do the extra job as you
did above.
But since you now have made an effort:
It was not specified that the arrays contained nullterminated strings,
I added the "// guaranteed to be a valid string" comment to indicate that
they are null-terminated (I know, I didn't say so in my first post). The
classes all have constructors which guarantee that the members are either
initialized to zero, or otherwise initialized to a valid string.
hence std::strlen is contra-indicated.
I understand your point, but they *will* be null-terminated.
It was specified that the arrays were of the same size, hence std::max is
contra-indicated.
I understand your point here too. The purpose of using strlen and max was
to determine the minimum number of characters I could swap and not lose any
data. There's no point in swapping the entire content of the arrays if they
don't need to be.
Now, if I were to explicitly do the work in the swap member function, then I
*could* do:
class Test
{
char s[10];
void swap( Test &rhs )
{
for ( int i=0; i<sizeof(s)/sizeof(s[0]); ++i )
{
std::swap( s[i], rhs.s[i] );
}
the for loop can be replaced by std::swap_ranges
std::swap_ranges(s, s + sizeof(s)/sizeof(s[0]), rhs.s);
}
};
That does avoid the extra strlen and max calls (which might affect the
efficiency of the function). However, I would prefer not to have to
re-write the same thing over and over in many different classes that contain
many char[] data members (DRY principle), which is why I wrote the
standalone strswap() function [so I wouldn't have to write the same code
over and over for every char[] data member in every class -- that would be
ridiculous!!].
So, for something that is re-usable, I opted for a standalone function. To
be generic enough to use it with any of the char[] data members in all those
classes, it was necessary to loop based on the data itself. Though, I
suppose I could also do:
void strswap( char * const c1, char * const c2, size_t length )
{
for ( int i=0; i<length; ++i )
{
std::swap( c1[i], c2[i] );
}
}
class Test
{
char s[C]; // where C is some constant
void swap( Test &rhs )
{
strswap( s, rhs.s, sizeof(s)/sizeof(s[0]) );
}
};
For the in-practice of providing swappable strings, use std::string.
I do use std::string (actually a variant of it) with newer code, but I don't
have that option here (not without a LOT of re-writing) because this is very
old, legacy code.
All of the examples do the same basic thing, and that is to swap the
contents of two char arrays. My question isn't whether or not strlen or max
is contra-indicated, as if it were a homework assignment. My question is,
how do I provide the no-fail guarantee when swapping an array of 'sometype'
(we might just as well be talking about an array of any type)?
So, to be more specific, is a loop a satisfactory way to swap array elements
and still provide the no-fail guarantee? I can't think of any other way --
I guess you meant "no throw guarantee",
the answer is Yes
can you?
--
Thanks
Barry