here is the main function in a program that i wrote in which i need to sort an array of characters, making the ones with an even ascii code at the beginning, and i wanna display how the array is sorted at every iteration.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main ()
{
int n, i,j;
char echange;
printf("array size : ");
scanf("%d", &n);
char t[n];
for (i=0; i<n; i )
{
printf("enter array elements : ");
scanf(" %c", &t[i]);
}
for (j=0; j<n; j )
for (i=0; i<n; i )
{
if ((t[i] % 2!=0) && (t[i 1] % 2 ==0) && (i != n-1))
{
strcpy(echange, t[i]);
strcpy(t[i], t[i 1]);
strcpy(t[i 1], echange);
printf (" %c (%d)", t[i], t[i]);
}
else
printf(" %c (%d)", &t[i], t[i]);
}
}
this problem is normally compiled, but the output is so weird :
array size : 3
enter array elements : d
enter array elements : f
enter array elements : g
2 └ (100) ┴ (102) ┬ (103) └ (100) ┴ (102) ┬ (103) └ (100) ┴ (102) ┬ (103)
Process returned 0 (0x0) execution time : 4.063 s
Press any key to continue.
so what is wrong with my code? and why how to use strcpy with single characters? and by the way, i tried without the strcpy function :
echange = t[i];
t[i] = t[i 1];
t[i 1] = echange;
and it didn't work neither
CodePudding user response:
The strcpy
function is used to copy an null terminated string from one char
array to another. What you're doing is copying single characters, so you're passing invalid arguments to the function, triggering undefined behavior.
With single characters you can just assign to them directly.
echange = t[i];
t[i] = t[i 1];
t[i 1] = echange;
CodePudding user response:
For starters this condition in the if statement
if ((t[i] % 2!=0) && (t[i 1] % 2 ==0) && (i != n-1))
can invoke undefined behavior when i
is equal to n- 1
because the expression t[i 1] can have a trap value. You need to write at least like
if ( ( i != n - 1 ) && (t[i] % 2!=0) && (t[i 1] % 2 ==0) )
Using the function strcpy
that expects arguments of pointer types that point to strings
char *strcpy(char * restrict s1, const char * restrict s2);
with objects of the type char
invokes undefined behavior.
Instead of these calls of the function
strcpy(echange, t[i]);
strcpy(t[i], t[i 1]);
strcpy(t[i 1], echange);
you could just write
echange = t[i];
t[i] = t[i 1];
t[i 1] = echange;
to swap two characters.
And as I understand instead of sorting the character array you need to split it into two partitions.
If you indeed want to sort the array then instead of trying to write the bubble sort method yourself you could use the standard C function qsort
as it is shown in the demonstration program below.
#include <stdio.h>
#include <stdlib.h>
int cmp( const void *p1, const void *p2 )
{
unsigned char c1 = *( const unsigned char * )p1;
unsigned char c2 = *( const unsigned char * )p2;
return c1 % 2 == c2 % 2 ? c1 - c2
: c1 % 2 - c2 % 2;
}
int main( void )
{
enum { N = 10 };
char s[N] = "9876543210";
printf( "%.*s\n", N, s );
qsort( s, N, sizeof( char ), cmp );
printf( "%.*s\n", N, s );
}
The program output is
9876543210
0246813579
If you want to use the method bubble sort method and to output the array after each iteration then the function that implements the method can look the following way as it is shown in teh demonstration program below.
#include <stdio.h>
void bubble_sort( char *s, size_t n )
{
const int N = n;
for ( size_t last = 0; !( n < 2 ); n = last )
{
for ( size_t j = last = 1; j < n; j )
{
unsigned char c1 = s[j-1], c2 = s[j];
if ( ( c1 % 2 == c2 % 2 && c2 < c1 ) ||
( c2 % 2 < c1 % 2 ) )
{
char tmp = s[j];
s[j] = s[j-1];
s[j-1] = tmp;
last = j;
}
}
printf( "%.*s\n", N, s );
}
}
int main( void )
{
enum { N = 10 };
char s[N] = "9876543210";
printf( "%.*s\n\n", N, s );
bubble_sort( s, N );
printf( "\n%.*s\n", N, s );
}
The program outpt is
9876543210
8765432109
8654321079
6843210579
6482103579
4628013579
4260813579
2406813579
2046813579
0246813579
0246813579