是否可以将 strcpy 与单个字符变量一起使用?

Posted

技术标签:

【中文标题】是否可以将 strcpy 与单个字符变量一起使用?【英文标题】:is it possible to use strcpy with single character variables? 【发布时间】:2022-01-13 13:36:54 【问题描述】:

这是我编写的程序中的主要功能,我需要在其中对字符数组进行排序,使字符的开头带有偶数 ascii 代码,并且我想显示每次迭代时数组的排序方式。

#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]);

    




 

这个问题正常编译,但是输出太诡异了:

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.

那么我的代码有什么问题?以及为什么如何将 strcpy 与单个字符一起使用?顺便说一句,我试过没有 strcpy 函数:

echange = t[i];
          t[i] = t[i+1];
          t[i+1] = echange;

它也没有用

【问题讨论】:

不,您不能将strcpy 与单个字符一起使用。它们不是字符串。您必须传递缓冲区的地址来保存字符串和要复制的字符串。并且字符串必须以 0 结尾。 你的编译器应该大声抱怨strcpy(echange, t[i]);。第一个参数应该是char *,而不是字符。如果你的编译器没有抱怨,那就换一个新的编译器。 (或打开诊断) printf(" %c (%d)", &amp;t[i], t[i]);´ %c` 需要 int 类型的参数而不是指针。你的编译器也应该警告这种不匹配。 我没有看你的逻辑,但看起来你想写 echange = t[i] 而不是 strcpy(echange, t[i]);。在尝试使用printf之前不要忘记添加一个空终止符@ 使用strcpy 复制单个字符有什么意义?您也不需要(不存在的)intcpy 函数来复制单个 int,对吗? 【参考方案1】:

strcpy 函数用于将一个以 null 结尾的字符串从一个 char 数组复制到另一个数组。您正在做的是复制单个字符,因此您将无效参数传递给函数,触发undefined behavior。

对于单个字符,您可以直接分配给它们。

  echange = t[i];
  t[i] = t[i+1];
  t[i+1] = echange;

【讨论】:

【参考方案2】:

对于初学者来说,if 语句中的这个条件:

if ((t[i] % 2!=0) && (t[i+1] % 2 ==0) && (i != n-1))

可以在i 等于n- 1 时调用未定义的行为,因为表达式 t[i+1] 可以有一个陷阱值。你至少需要这样写:

if ( ( i != n - 1 ) && (t[i] % 2!=0) && (t[i+1] % 2 ==0) )

使用函数strcpy,它需要指向字符串的指针类型的参数

char *strcpy(char * restrict s1, const char * restrict s2);

char 类型的对象调用未定义的行为。

代替这些函数调用:

          strcpy(echange, t[i]);
          strcpy(t[i], t[i+1]);
          strcpy(t[i+1], echange);

你可以写:

          echange = t[i];
          t[i] = t[i+1];
          t[i+1] = echange;

交换两个字符。

据我了解,您需要将字符数组拆分为两个分区,而不是对字符数组进行排序。

如果您确实想要对数组进行排序,那么您可以使用标准 C 函数 qsort,而不是尝试自己编写冒泡排序方法,如下面的演示程序所示。

#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 );

程序输出是

9876543210
0246813579

如果你想使用方法冒泡排序方法并在每次迭代后输出数组,那么实现该方法的函数可以如下面的演示程序所示:

#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 );

程序输出为:

9876543210

8765432109
8654321079
6843210579
6482103579
4628013579
4260813579
2406813579
2046813579
0246813579

0246813579

【讨论】:

@chux-ReinstateMonica 谢谢。 II 不专心。:)

以上是关于是否可以将 strcpy 与单个字符变量一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

理解 char *、char[] 和 strcpy()

strcpy 与 strdup

为啥不能用赋值语句将一个字符串常量直接赋给一个字符数组

我可以将 asm 函数与 c - 字符串变量而不是字符串文字作为参数一起使用吗? [复制]

如何从 char 数组中清除单个字符?

在 Node JS 中使用 MSQL XDEVAPI,我可以将多个调用链接在一起吗?