Strange output from Counting Sort in C - c

I have the following Counting Sort function
/*
*File: countingSort.c
*Description: A counting sort subroutine. Takes as input an array of integers.
* an array length and a range. All values in the input array must fall within [0, range].
* Takes O(range + arrayLen) time and O(range + arrayLen) extra space
*
*/
#include "countingSort.h"
int* countingSort(int unsorted[], int arrayLen, int range) {
int store[range + 1];
int sorted[arrayLen];
for ( int i = 0; i <= range; i++ ) {
store[i] = 0;
}
for ( int i = 0; i < arrayLen; i++ ) {
sorted[i] = 0;
}
for ( int j = 0; j < arrayLen; j++ ) {
store[unsorted[j]] ++;
}
for ( int i = 1; i <= range; i++ ) {
store[i] += store[i-1];
}
for( int j = arrayLen - 1; j >= 0; j-- ) {
sorted[store[unsorted[j]]] = unsorted[j];
store[unsorted[j]] --;
}
return sorted;
}
The function is giving me really strange output. The output is nothing like the input most of the times but sometimes it just works.
Why is this happening?
I am calling it from another file called cSortTest.c.
That file looks like this
/*
*File: cSortTest.c
*Description: Tests countingSort.c
*
*/
#include <stdio.h>
#include "countingSort.h"
int main() {
int data[8] = { 2, 1, 9, 4, 4, 56, 90, 3 };
int* p;
p = countingSort(data, 8, 90);
for ( int i = 0; i < 8; i++ ) {
printf("%d Element: %d\n", i, *(p+i) );
}
}

You are returning a local array variable. This variable is destroyed when the function exits, making the address to it no longer safe or valid to access. In fact accessing it will give you what is called undefined behavior, which explains why it sometimes appears to "work".
This is a classic beginner's mistake in C. You must either have the caller pass in the desired destination array, or use malloc() to allocate "persistent" heap memory and return that:
int* countingSort(int unsorted[], int arrayLen, int range) {
int *sorted = malloc(arrayLen * sizeof *sorted );
if (sorted== NULL)
return NULL;
/* rest of sorting */
return sorted;
}
The arrayLen * sizeof *sorted expression computes the number of bytes required for the allocation. There's no need to use calloc() which clears the memory; you're going to overwrite each element so clearing it is just wasted effort.

Related

multi pointers in function in c

i'm not good at english.
i declare array and two pointers.
the maxPtr pointer should have array arr's maximum number adress.
and minPtr pointer should have array arr's minimum number adress.
so i declare the function and this has two double-pointer to give maxPtr and minPtr proper adress.
but whenever i run this code, the program is not fully run.
it doesn't output the result( printf("%d",*maxPtr) ,printf("%d", *minPtr, printf("Hi");
this program is run at vscode in mac.
what make it error?
#include <stdio.h>
void MaxAndMin(int* str,int** max, int** min)
{
int i;
int maxnum=0,minnum=0;
for(i=0; i<5; i++)
{
if(maxnum< str[i])
{
maxnum =str[i];
*max = &str[i];
}
if(minnum > str[i])
{
minnum = str[i];
*min = &str[i];
}
}
}
int main(void)
{
int i,len;
int* maxPtr;
int* minPtr;
int arr[5]={};
for(i=0; i<5; i++)
{
printf("%d번째 정수입력 입니다.",i+1);
scanf("%d", &arr[i]);
}
MaxAndMin(arr,&maxPtr,&minPtr);
printf("%d",*maxPtr);
printf("%d",*minPtr);
printf("Hi");
return 0;
}
the result is
> Executing task: ./test <
1번째 정수입력 입니다.1
2번째 정수입력 입니다.2
3번째 정수입력 입니다.3
4번째 정수입력 입니다.4
5번째 정수입력 입니다.5
Terminal will be reused by tasks, press any key to close it.
For starters this initialization of an array
int arr[5]={};
is incorrect in C. You have to write
int arr[5]={ 0 };
Secondly using the magic number 5 within the function makes the function useless in general. You need to pass to the function the size of the array.
The initial value 0
int maxnum=0,minnum=0;
of these variables makes the function even more less useful. In general the array can contain either all elements positive or all elements negative.
And you need to flush the output buffer using for example the new line character '\n' in calls of printf.
The function can be declared and defined the following way as it is shown in the demonstration program below.
#include <stdio.h>
void MaxAndMin( const int a[], size_t n, int **max, int **min )
{
*max = ( int * )a;
*min = ( int * )a;
for ( size_t i = 1; i < n; i++ )
{
if ( **max < a[i] )
{
*max = ( int *)( a + i );
}
else if ( a[i] < **min )
{
*min = ( int * )( a + i );
}
}
}
int main( void )
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
int *maxPtr = NULL;
int *minPtr = NULL;
MaxAndMin( a, N, &maxPtr, &minPtr );
printf( "The maximum value is %d at position %tu\n",
*maxPtr, maxPtr - a );
printf( "The minimum value is %d at position %tu\n",
*minPtr, minPtr - a );
}
The program output is
The maximum value is 9 at position 9
The minimum value is 0 at position 0
Pay attention to that the first parameter of the function should have the qualifier const because passed arrays to the function are not changed within the function.
The main issue is that the minnum is set at zero, which would only work if array had a negative value.
Setting minimum = star[0] also would not work!!! Because in the case of str[0] having negative value, *min never gets changed.
Also, I recommend to always initialize all variables in the declaration, especially pointers (because they may theoretically cause accidental access to memory).
Full solution:
#include <stdio.h>
int MaxAndMin(int* str, int** max, int** min)
{
int i;
int maxnum = 0;
int minnum = str[0] + 1;
for(i=0; i<5; i++)
{
if(maxnum < str[i])
{
maxnum = str[i];
*max = &str[i];
}
if(minnum > str[i])
{
minnum = str[i];
*min = &str[i];
}
}
return 0;
}
int main(void)
{
int i = 0;
int len = 0;
int* maxPtr = NULL;
int* minPtr = NULL;
int arr[5]={};
for(i=0; i<5; i++)
{
printf("Enter number %d: ",i+1);
scanf("%d", &arr[i]);
}
MaxAndMin(arr, &maxPtr, &minPtr);
printf("%d",*maxPtr);
printf("%d",*minPtr);
printf("Hi");
return 0;
}

how can I use less variables in my program?

I had to make a program that have an array of numbers, and then I need to make a function that get the arr[0] and the length of the array, and then it will print all the numbers without the duplicate ones.
I made this program and it worked good but I feel like I used too much variables for this program. (I started to learned in the last few weeks so its not looks very good)
#include <stdio.h>
#define N 10
void print_set(int *arr, int n) {
int i = 1;
int duplicate_num, check_num, count;
printf(" %d", *arr); //printing the first number (arr[0]).
//starting to check the other number. if they new I'll print them. (start from arr[1]).
arr++;
while (i < n) {
if (*arr != duplicate_num) {
printf(" %d", *arr);
check_num = *arr;
// becouse I found new number, I change it no be equal to the first duplicate_num. (if there are more like him, I change them too).
while (i < n) {
if (*arr == check_num) {
*arr = duplicate_num;
}
arr++;
i++;
count++;
}
i = i - count;
arr = arr - count;
count = 0;
}
arr++;
i++;
}
}
int main() {
int arr[N] = {4, 6, 9, 8, 6, 9, 6, 1, 6, 6};
print_set(&arr[0], N);
return 0;
}
output for this program: 4 6 9 8 1
I'll be happy to see good method to make this program less messy.
For starters the function has undefined behavior. The user can pass 0 as the second argument. It means that the array is empty and has no elements. In this case the expression *arr is undefined.
The second problem is using the uninitialized variable duplicate_num in this if statement
if (*arr != duplicate_num) {
and the uninitialized variable count
count++;
Another problem is that the function changes the array
if (*arr == check_num) {
*arr = duplicate_num;
}
If you need only to output unique values in an array then the source array shall not be changed.
The function can be defined for example the following way
void print_set( const int *a, size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
size_t j = 0;
while ( j != i && a[i] != a[j] ) ++j;
if ( j == i ) printf( "%d ", a[i] );
}
putchar( '\n' );
}

how to filter an array and overwrite that

I need to filter some specific elements from an array. I write the code which work perfectly:
#include <stdio.h>
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
int main (int argc, char *argv[]) {
// our initial array
int x[] = {1,2,-3,4,5};
// initialize filtered_array with pointer
int *filtered;
int upper_bound = 4, lower_bound = 1, i, j=0, total = -1,result;
size_t n = NELEMS(x);
printf("size of the main array: %d\n",n);
// check which element satisfy the condition and count them
for (i=0;i<n;++i)
{
total = ((x[i] >= lower_bound) && (x[i] <= upper_bound)) ? total+1 : total;
};
// allocate array size for filtered array
filtered = (int*) calloc(total,sizeof(int));
for (i=0;i<n;++i)
{
// filter element from main array and store them in filtered array
result = ((x[i] >= lower_bound) && (x[i] <= upper_bound)) ? 1 : 0;
if(result) {
filtered[j] = x[i];
++j;
};
};
for (i = 0; i<total+1; ++i){
printf("%d ",filtered[i]);
};
return 0;
}
But can I avoid to create a new array like I used filtered and dynamically do this for the main array by some overwrite trick?
For starters your program is incorrect.
Firstly you need to include the header <stdlib.h>
#include <stdlib.h>
Secondly, initially total is set to -1
total = -1
So if the original array contains only one element that satisfies the condition then total will be equal to 0 due to this statement
total = ((x[i] >= lower_bound) && (x[i] <= upper_bound)) ? total+1 : total;
As a result this statement
filtered = (int*) calloc(total,sizeof(int));
is trying to allocate a memory with the size equal to 0. If the memory will be allocated (it is implementation defined) then you may not write anything in this memory. Otherwise the program will have undefined behavior.
In any case you are counting elements that satisfy the condition incorrectly and hence allocating a block of memory of an incorrect size.
Also there is no sense to insert a null statement after compound statements as you are doing
for (i=0;i<n;++i)
{
//...
};
^^^
Remove such redundant semicolons.
And you are using an incorrect conversion specifier in this call of printf.
printf("size of the main array: %d\n",n);
^^^
You have to write
printf("size of the main array: %zu\n",n);
^^^
As for your question
But can I avoid to create a new array like I used filtered and
dynamically do this for the main array by some overwrite trick?
then what you need is to change the array in place and to track the number of actual elements that satisfy the condition.
For example
int x[] = {1,2,-3,4,5};
// initialize filtered_array with pointer
size_t n = NELEMS(x);
int upper_bound = 4, lower_bound = 1;
printf( "size of the main array: %zu\n", n );
size_t m = 0;
for ( size_t i = 0; i < n; ++i )
{
if ( x[i] >= lower_bound) && x[i] <= upper_bound )
{
if ( m != i )
{
x[m] = x[i];
}
++m;
}
}
for ( size_t i = 0; i < m; ++i )
{
printf( "%d ", x[i] );
}
putchar( '\n' );
If you need to reallocate the original array according to the number of elements that satisfy the condition then the code can look for example the following way
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
//...
size_t n = 5;
int *x = malloc( n * sizeof( int ) );
memcpy( x, ( int[] ){ 1, 2, -3, 4, 5 }, n * sizeof( int ) );
int upper_bound = 4, lower_bound = 1;
printf( "size of the main array: %zu\n", n );
size_t m = 0;
for ( size_t i = 0; i < n; ++i )
{
if ( x[i] >= lower_bound) && x[i] <= upper_bound )
{
if ( m != i )
{
x[m] = x[i];
}
++m;
}
}
if ( m != n )
{
int *tmp = realloc( x, m * sizeof( int ) );
if ( tmp != NULL )
{
x = tmp;
for ( size_t i = 0; i < m; ++i )
{
printf( "%d ", x[i] );
}
putchar( '\n' );
}
}
free( x );
What you are looking for is called modification (in this case filtering) in place.
That's even pretty simple:
int* filter(int* begin, int* end)
{
int* pos = begin; // start at the beginning of the array
for(; begin != end; ++begin)
{
if(*begin != 0) // your appropriate condition!
// this one filters out all zero values...
{
*pos++ = *begin; // copy current element to retain into
// first position not yet used
// (pos always points to one element past
// the last one retained!)
}
}
return pos; // as above, points to one past the last element retained
}
The return value is important to know how many elements remained.
If you prefer, you can instead write an index-based variant avoiding pointer arithmetics...
The basic idea about the filtering algorithm is that you just copy the elements towards the front, overwriting those values that either are filtered away or have already been copied.
Edit: Additional explanations:
begin and end pointers are to be passed as pointer to first element of the array and pointer to one past the array (typical C++ semantics when iterating over C++ STL containers, though these come with their own iterator types instead of pointers...).
So you'd call the function like:
int array[N];
int* newEnd = filter(array, array + sizeof(array)/sizeof(*array));
This is typical C++ semantics when iterating over STL containers (though these come with their specific iterator types instead of poitners).
If you don't like:
size_t filter(size_t length, int array[length]) // note: length as array subscript
// is ignored anyway...
{
int* pos = array;
int* begin = array;
int* end = array + length;
// now following the identical loop as above
return pos - array; // pointer difference; if pos points one past the last
// element you get the *number* of elements retained
}
About *pos++ = *begin: That's nothing special and any good C book should explain that nicely to you...
It copies the value begin points to to the address pos points to and increments pos afterwards.
An indexing loop doing the same might look as follows:
size_t pos = 0;
for(size_t i = 0; i < length; ++i)
{
array[pos++] = array[i]
}
return pos;

array of scores

Given an array of scores where 60 is the highest and 36 is the passing. The function will return an array of all passing scores
#include <stdio.h>
#include <stdlib.h>
int* passingScores (int scores[], int size);
int main () {
int B[] = {55, 35, 60, 25, 10, 43}; //expect display 55,60,43
int size = 6;
int* C;
int i;
C = passingScores(B, size);
for (i=0; i<size; i++) {
printf ("%d\n", C[i]);
}
return 0;
}
code of function:
int* passingScores (int scores[], int size) {
int i;
int passingScore = 36;
int* pass;
pass = (int*)malloc(sizeof(int)*size);
if (pass != NULL) {
for (i=0; i<size; i++) {
if (scores[i] > passingScore){
pass[i] = scores[i];
}
}
}
return pass;
}
elements in the array in main are:
55, 35, 60, 25, 10, 43
the result after the function call would be:
55, 0, 60, 0, 0, 43
but I wanted to have a result like:
55, 60, 43
pls help :) thank you!
For starters according to the C Standard the function main without parameters shall be declared like
int main( void )
You should not use magic numbers like in this declaration
int size = 6;
The size of the original array can be calculated.
The function passingScores does not change the original array. So its first parameter should be declared with the qualifier const like
const int scores[]
The user of the function need to know how many elements were passed the test. So it is better when the function returns the number of the passed scores and accepts the pointer to the potentially allocated array from the user by reference.
Instead of the magic number 36 declared within the function
int passingScore = 36;
it is better to pass such a number as a function argument. In this case the function will be more flexible.
You are allocating redundant memory in the function. You should at first count the number of the passed scores. The original array of scores can be very big but its elements that passed the test can be very few.
And for the array pointed to by the pointer pass you need to use a separate index to store selected values sequentially.
And do not forget to free the allocated memory.
Here is a demonstrative program that shows how the function can be implemented.
#include <stdio.h>
#include <stdlib.h>
size_t passingScores( const int scores[], size_t size, int passingScore, int **passed );
int main( void )
{
int scores[] = { 55, 35, 60, 25, 10, 43 };
const size_t SIZE = sizeof( scores ) / sizeof( *scores );
int passingScore = 36;
int *passed_scores = NULL;
size_t n = passingScores( scores, SIZE, passingScore, &passed_scores );
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", passed_scores[i] );
}
putchar( '\n' );
free( passed_scores );
return 0;
}
size_t passingScores( const int scores[], size_t size, int passingScore, int **passed )
{
size_t n = 0;
for ( size_t i = 0; i < size; i++ )
{
n += passingScore < scores[i];
}
if ( n != 0 )
{
*passed = malloc( n * sizeof( int ) );
if ( *passed != NULL )
{
for ( size_t i = 0, j = 0; i < size; i++ )
{
if ( passingScore < scores[i] ) ( *passed )[j++] = scores[i];
}
}
}
return n;
}
The program output is
55 60 43
The following code includes several suggestions, including adding an additional index to keep track of only passing scores, and using calloc instead of malloc to initialize the array. (see other comments and suggested changes below.)
int* passingScores (int scores[], int size);
int main (void) // Or use: int main(int argc, char *argv[]){...}
{ //But never: int main(){...}
int B[] = {55, 35, 60, 25, 10, 43}; //expect display 55,60,43
//int size = 6;//do not use magic numbers
int size = sizeof(B)/sizeof(B[0]);//yields number of elements in array B
int* C;
int i;
C = passingScores(B, size);
if(C)//test before using
{
for (i=0; i<size; i++) {
if(C[i] != 0) printf ("%d\n", C[i]); //include only passing scores
//(excluding zeros)
}
free(C);//free memory when done.
}
return 0;
}
int* passingScores (int scores[], int size) {
int i, j = 0;//additional index j to track passing scores.
int passingScore = 36;
int* pass;
//pass = (int*)malloc(sizeof(int)*size);//allocates un-initialized memory
pass = calloc(size, sizeof(int));//calloc initializes memory to zero
if (pass != NULL) {
for (i=0; i<size; i++) {
if (scores[i] > passingScore){
pass[j] = scores[i];
j++;//indexed only when passing score
}
}
}
return pass;
}
Some notes on using calloc/malloc...
For your purposes, the contents of memory allocated using malloc is provided as is, including whatever contents happened to occupy that space before your process was granted ownership. On my machine and using malloc, the space is occupied with:
pass[0] == 0xBAADFOOD (-1163005939)
pass[1] == 0xBAADFOOD
pass[2] == 0xBAADFOOD
pass[3] == 0xBAADFOOD
pass[4] == 0xBAADFOOD
pass[5] == 0xBAADFOOD
So, the way in which you are selectively writing to some elements of that memory would leave that original content in some of the other areas of that memory block, causing problems when outputting the results.
When using malloc in this way it is recommended to initialize the memory before using:
pass = malloc(size * sizeof(int));
if(pass)
{
memset(pass, 0, size*sizeof(int));
...
Resulting in:
pass[0] == 0x00000000
pass[1] == 0x00000000
pass[2] == 0x00000000
pass[3] == 0x00000000
pass[4] == 0x00000000
pass[5] == 0x00000000
Using calloc allocates the memory just as malloc does, but then clears it before returning, saving the need for you to clear it with memset.
Note also it is not necessary, or recommended to cast the return of [m][c]alloc.
The problems lies with this statement:
pass[i] = scores[i];
You don't want to copy the score into the element with the same index; you want to copy it into the first "free" slot. You'll need to keep track of how elements of pass are being used.
There's a second problem: You output size numbers, even if there are fewer passing grades.
In this case, rather than having to communicate the number of elements in the returned array to the caller, we could simply place a 0 at the end to indicate the end. But we have to be careful of the case where all the grades are passing grades!
A minor third problem: You are considering a grade of 36 to be a failing grade! Let this be a lesson in testing: Whenever you do testing, always test at and around the limits (so you'd test with scores of 35, 36 and 37 in this case).
Finally, you dynamically allocate an array, but you never free it. It's not critical that you free it because you'd do so just before exiting the program, but that's a bad habit to get into. (One possible consequence is that it would cause the output of tools such as valgrind to become very noisy if you decide to use it to help resolve a crash.)
#include <stdio.h>
#include <stdlib.h>
int* getPassingScores(const int* scores, int num_scores) {
const int passingScore = 36;
// calloc is like malloc, but the memory will
// be efficiently initialized to 0. This means
// we don't need to do pass[j] = -1; later.
// Need to make sure we have enough space
// when all the grades are passing grades!
int* pass = calloc(num_scores, sizeof(int));
if (!pass)
return NULL;
for (int i=0, j=0; i<num_scores; ++i) {
if (scores[i] >= passingScore) {
pass[j++] = scores[i];
}
}
return pass;
}
int main(void) {
int scores[] = {55, 35, 60, 25, 10, 43};
int num_scores = sizeof(scores)/sizeof(*scores);
int* passingScores = getPassingScores(scores, num_scores);
for (int i=0; passingScores[i]>0; ++i) {
printf("%d\n", passingScores[i]);
}
free(passingScores);
return 0;
}
Of course, the following would suffice:
#include <stdio.h>
int main(void) {
int scores[] = {55, 35, 60, 25, 10, 43};
int num_scores = sizeof(scores)/sizeof(*scores);
const int passingScore = 36;
for (int i=0; i<num_scores; ++i)
if (scores[i] >= passingScore)
printf("%d\n", scores[i]);
}

How to pass an array of strings to a function in this program?

I am a complete beginner with C and we have an assignment in class to take a given list of strings, put them in an array of strings, and pass that to a user-defined sort function that prints them in alphabetical order. Whenever I run my code, it does not give any compiler errors, but it also crashes immediately at runtime. Debugging gives me a segmentation fault, but it does not give me a specific line that caused it. I am running my code through the gcc compiler included in Dev C++.
Here is my code. Any help would be appreciated. I think my problem is trying to pass an array of strings to the function, but I haven't been able to find any answers on the subject that I could understand.
#include <stdio.h>
#include <string.h>
void sort(char *[]);
int main()
{
char *states[4] = {0};
states[0] = "Florida";
states[1] = "Oregon";
states[2] = "California";
states[3] = "Georgia";
sort(states);
return 0;
}
void sort(char *ptr[])
{
int i, j;
char temp[20];
for ( i = 1; i <= 4; i++ )
{
for ( j = 1; j <= 4; j++ )
{
if (strcmp(ptr[j-1], ptr[j]) > 0)
{
strcpy(temp, ptr[j-1]);
strcpy(ptr[j-1], ptr[j]);
strcpy(ptr[j], temp);
}
}
}
int x;
for ( x = 0; x < 4; x++ )
{
printf("%s", ptr[x]);
printf("\n");
}
}
Issues I see:
You are using the wrong indices in the for loops.
Instead of:
for ( i = 1; i <= 4; i++ )
{
for ( j = 1; j <= 4; j++ )
use:
for ( i = 0; i < 4; i++ ) // Keep the values in the range 0 - 3.
{
for ( j = 0; j < 4; j++ )
You are modifying read-only memory.
When you use:
states[0] = "Florida";
states[0] has the value of a read-only address that contains the string "Florida". If you modify the values at that address, which you are doing in sort, you are entering undefined behavior territory.
You can fix the problem by switching pointers instead of copying the values.
// Use char* for temp instead of an array
char* temp;
if (strcmp(ptr[j-1], ptr[j]) > 0)
{
temp = ptr[j-1];
ptr[j-1] = ptr[j];
ptr[j] = temp;
}
Addendum, in response to comment by OP
The following version of sort works for me:
void sort(char *ptr[])
{
int i, j;
char* temp;
for ( i = 0; i < 4; i++ )
{
// NOTE:
// This is different from your version.
// This might fix your problem.
for ( j = i+1; j < 4; j++ )
{
if (strcmp(ptr[j-1], ptr[j]) > 0)
{
temp = ptr[j-1];
ptr[j-1] = ptr[j];
ptr[j] = temp;
}
}
}
for ( i = 0; i < 4; i++ )
{
printf("%s", ptr[i]);
printf("\n");
}
}
The cause of crash is j <= 4. The other problem is that you want to swap pointers to string and not the chars.
void sort(char *ptr[])
{
int i, j;
char *temp;
for (i = 0; i < 4; i++) // sticking to array boundary convention
{
for ( j = 1; j < 4; j++ )
{
if (strcmp(ptr[j-1], ptr[j]) > 0)
{
// swap pointers
tmp = ptr[j];
ptr[j] = ptr[j-1];
ptr[j-1] = ptr[j];
}
}
}
for (i = 0; i < 4; i++)
printf("%s\n", ptr[i]);
}
C's Standard Library already comes with a function to sort arbitrary arrays of data. It is called qsort.
qsort can sort arrays based on any criterion you supply using its fourth argument, the comparison function. In this case, we have a natural comparison function which we would like to shoehorn into using with what qsort expects.
So, mycmpstr below casts the incoming pointers appropriately, and returns the result of comparing strings using strcmp. We know that qsort will be calling our comparison function with constant pointers to constant char pointers, and we 'cast' appropriately.
Keep in mind that you are sorting pointers to character arrays. That means, you do not need to move the strings themselves, just the pointers. You use strcmp to decide which pointer should come before which based on the ordering of the strings to which they point.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int mycmpstr(const void *p, const void *q) {
const char *const *x = p;
const char *const *y = q;
return strcmp(*x, *y);
}
int main(void)
{
int i;
const char *states[] = {
"Florida", "Oregon", "California", "Georgia"
};
qsort(
states,
4,
sizeof(char *),
mycmpstr
);
for (i = 0; i < 4; i += 1) {
puts(states[i]);
}
return 0;
}
Output:
$ clang -Wall -O1 sortex.c -o sortex
$ ./sortex
California
Florida
Georgia
Oregon

Resources