views:

211

answers:

3

I have a 2d array of chars where in each row I store a name... such as this:

J O H N
P E T E R
S T E P H E N
A R N O L D
J A C K

How should I go about sorting the array so that I end up with

A R N O L D
J A C K
J O H N
P E T E R
S T E P H E N

These is a 2d array of chars..... no strings or char points.....

A: 

Don't bubble sort - point number 1.

Point number two:

Compare the first character of each sub array (i.e. array[x][0]) if it needs to be shifted then shift all characters in sub-array x using a while loop...or by saving the sub-array and shifting it like that...

Dwaine Bailey
+2  A: 
#define MAX_NAME 8

char names[][MAX_NAME] = {"JOHN", "PETER", "STEPHEN", "ARNOLD", "JACK"};
 // strcmp is really (int (*)(const char *, const char *)), so we cast.
qsort(names, sizeof(names) / MAX_NAME, MAX_NAME, 
  (int (*)(const void *, const void *)) strcmp);

Note that this is probably not a bubble sort.

Matthew Flaschen
error: invalid conversion from ‘int (*)(const char*, const char*)throw ()’ to ‘int (*)(const void*, const void*)’|
I added a cast, which should resolve that error. Basically, strcmp takes `const char*`, while qsort expects a function that takes `const void*`.
Matthew Flaschen
I get no errors now, but it's doing something bc when I print the array nothing gets printed. but before calling this method everything gets printed just fine
I made a simple [working demo](http://codepad.org/Cdogcl6R). It shows it printing before and after.
Matthew Flaschen
yeah but that's an array of char pointers..... I have a 2d array of char so that's really not working.
No it's not. It's a two-dimensional array, 5 rows by 8 columns. Thomas's is a array of char pointers. Maybe you should post the way your array is declared.
Matthew Flaschen
A: 

C++ doesn't support copying or comparing C-style arrays, but it does support such operations on very thinly-wrapped C-style arrays. Try boost::array, which is the same as tr1::array and std::array in C++0x.

Or, roll your own:

#include <algorithm>

template< class T, size_t s >
struct array {
    T arr[s]; // public data, no destructor, inheritance, virtuals, etc
              // => type is aggregate
    operator T const *() const { return arr; }
    operator T *() { return arr; } // as close as we can get to array emulation

    friend bool operator< ( array const &l, array const &r )
        { return std::lexicographical_compare( l, l+s, r, r+s ); }
};

array< char, 10 > names[] // aggregate initialization — this is standard C++
    = { "JOHN", "PETER", "ARNOLD", "JACK" };

#include <iostream>
using namespace std;

int main() {
sort( names, names + sizeof names / sizeof *names );

for ( array<char,10> *s = names; s != names + sizeof names/sizeof*names; ++ s )
    cerr << *s << endl;
}

If your compiler doesn't insanely add padding to the above structure, you can safely reinterpret_cast a C-style array an an array:

template< class T, size_t s >
array< T, s > &wrap_arr( T (&a)[s] ) {
    return reinterpret_cast< array<T,s> & >( a );

        // make sure the compiler isn't really wacky...
        // I would call this optional:
    BOOST_STATIC_ASSERT( sizeof( T[s] ) == sizeof( array<T,s> ) );
}

char names_c[][10] // or whatever C input from wherever
    = { "JOHN", "PETER", "ARNOLD", "JACK" };

array<char, 10> *names = &wrap_arr( names_c[0] );
Potatoswatter