Home > OS >  is it possible to use strcpy with single character variables?
is it possible to use strcpy with single character variables?

Time:12-09

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
  • Related