Limited to stdio.h
If you are limited to using what is provided in stdio.h, then you simply have to write similar string handling functionality to what you would require from string.h. For sorting, unless you want to use a partitioning sort like quicksort or mergesort, you would be limited to a nested loop sort -- which are simpler to write -- but much much slower. (but for a 1000 or so strings, it doesn't matter, 100,000 - then there will be a perceivable difference)
To compare strings, you can write a simple strcmp() like function that requires no additional header, e.g.
/** string compare without string.h */
int strcmp_nohdr (const char *a, const char *b)
{
if (!a && !b) return 0;
if ( a && !b) return 1;
if (!a && b) return -1;
for (; *a && *a == *b; a++, b++) {}
return (*a > *b) - (*a < *b);
}
If you are not declaring an additional set of pointers to sort, then you will need to copy strings between the rows (1D arrays) in your 2D array. You can write a simple strcpy() like function that needs no header as:
/** string copy wihout string.h */
char *strcpy_nohdr (char *dest, const char *src)
{
char *p = dest;
do {
*p++ = *src;
} while (*src++);
return dest;
}
Finally, the only other thing you need is a sort function. (you will not be able to write a quick qsort() replacement) The meager Bubblesort will do. You can write a function to sort your 2D array of strings as:
#define NCHR 50
/** bubble sort of strings in 'a' (highly inefficient) */
void bubblesort2D (char (*a)[NCHR], size_t n)
{
size_t i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < (n-1); j++) {
if (strcmp_nohdr(a[j], a[j + 1]) > 0) {
char temp[NCHR];
strcpy_nohdr (temp, a[j + 1]);
strcpy_nohdr (a[j + 1], a[j]);
strcpy_nohdr (a[j], temp);
}
}
}
}
If you put those altogether in a short example (the same used before with qsort(), you would have:
#include <stdio.h>
#define NCHR 50
/** string compare without string.h */
int strcmp_nohdr (const char *a, const char *b)
{
if (!a && !b) return 0;
if ( a && !b) return 1;
if (!a && b) return -1;
for (; *a && *a == *b; a++, b++) {}
return (*a > *b) - (*a < *b);
}
/** string copy wihout string.h */
char *strcpy_nohdr (char *dest, const char *src)
{
char *p = dest;
do {
*p++ = *src;
} while (*src++);
return dest;
}
/** bubble sort of strings in 'a' (highly inefficient) */
void bubblesort2D (char (*a)[NCHR], size_t n)
{
size_t i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < (n-1); j++) {
if (strcmp_nohdr(a[j], a[j + 1]) > 0) {
char temp[NCHR];
strcpy_nohdr (temp, a[j + 1]);
strcpy_nohdr (a[j + 1], a[j]);
strcpy_nohdr (a[j], temp);
}
}
}
}
int main (void) {
char strings[][NCHR] = { "zebra", "alligators", "frogs", "racoons", "opossums" };
size_t n = sizeof strings / sizeof *strings;
bubblesort2D (strings, n);
for (size_t i = 0; i < n; i++)
puts (strings[i]);
}
Example Use/Output
The results are the same as before:
$ ./bin/sort_2d_strings_stdio
alligators
frogs
opossums
racoons
zebra
Since I originally wrote the qsort() answer, I'll leave it below as the way you would want to handle sorting (whatever array you are sorting) in practice.
In Practice Use qsort()
C provides qsort() that will sort arrays of any object based on the compare function you write to tell qsort() how elements of the array are to be compares. With strings, you just want to return the result of strcmp(). Each argument to the compare function ia a Pointers to an element of your array. Since it is a void* pointer, you must cast the pointer back to the correct type.
Recall in C that a 2D array is simply an array of 1D arrays. In your case it is a array of 50-character arrays. A pointer to an array of 50-chars has the type char (*)[50], so your qsort() compare function can be written as follows:
int cmpstr50 (const void *a, const void *b)
{
const char *pa = *(char (*)[50])a,
*pb = *(char (*)[50])b;
return strcmp (pa, pb);
}
Where each of the parameters is a pointer to an array of char [50]. Nothing could be easier. Moreover the algorithm used by qsort() will be orders of magnitude faster than what you write with nested loops.
A complete example for your case would be:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int cmpstr50 (const void *a, const void *b)
{
const char *pa = *(char (*)[50])a,
*pb = *(char (*)[50])b;
return strcmp (pa, pb);
}
int main (void) {
char strings[][50] = { "zebra", "alligators", "frogs", "racoons", "opossums" };
size_t n = sizeof strings / sizeof *strings;
qsort (strings, n, sizeof *strings, cmpstr50);
for (size_t i = 0; i < n; i++)
puts (strings[i]);
}
Where after writing your compare function, all it takes to sort the array of strings (or array of anything) is a single call to qsort():
qsort (strings, n, sizeof *strings, cmpstr50);
Much simpler than trying to reinvent the wheel.
Example Use/Output
$ ./bin/qsort_2d_strings
alligators
frogs
opossums
racoons
zebra
Let me know if you have further questions.
strcmp()andstrcpy(), I'd probably write my own functions for those tasks.whileloop does.