繁体   English   中英

在C中将字符从一个字符串参数复制到另一个

[英]Copying a character from one string argument to another in C

在尝试将 s 中的第一个字符替换为 t 后,以下程序崩溃且没有错误消息。 该程序的目的是测试两个字符串 s 和 t 是否同构:

#include <stdio.h>
#include <string.h>
#include <stdbool.h>

bool isIsomorphic(char *s, char *t);

int main()
{
    isIsomorphic("egg", "add");
}

bool isIsomorphic(char *s, char *t)
{
    //create two other char pointers for the characters one position before s and t.
    char *preS = s; 
    char *preT = t; 

    //replace first character in s with t.
    *s = *t //CRASHES HERE

    //increment both pointers to their second character.
    s ++;
    t ++;

    //run through t
    while(t != NULL)
    {
        //if the characters in both strings are either a. both equal to their previous or b. both different to their previous:
        if(((strcmp(t, preT) == 0) && (strcmp(s, preS) == 0)) || (((strcmp(t, preT) != 0) && (strcmp(s, preS) != 0))))
        {
            //copy t into s and shift both pointers along.
            *s = *t;
            s ++;
            t ++;
        }
        else
        {
            printf("not isomorphic\n");
            return false;
        }
    }
    printf("isomorphic\n");
    return true;
}

为什么会这样? 任何帮助,将不胜感激。

禁止修改字符串文字。 尝试这样做会调用未定义的行为

在这种情况下,指针在赋值后递增,并且在调用isIsomorphic函数后不引用字符串,因此您应该删除无意义和有害的赋值( *s = *t; )。

如果您想稍后引用修改后的字符串,您应该将要修改的字符串存储在一个可修改的数组中,如下所示:

int main(void)
{
    char str[] = "egg";
    isIsomorphic(str, "add");
}

您正在使用字符串文字

isIsomorphic("egg", "add");

你在函数内改变的是同isIsomorphic

*s = *t //CRASHES HERE

您不能更改字符串文字。 任何更改字符串文字的尝试都会导致未定义的行为。

来自 C 标准(6.4.5 字符串文字)

7 如果这些数组的元素具有适当的值,则未指定这些数组是否不同。 如果程序尝试修改这样的数组,则行为未定义。

但无论如何,该功能是不正确的。

首先,函数不应更改传递给它的字符串。 也就是说它应该被声明为

bool isIsomorphic( const char *s, const char *t);

还有这些 if 语句中函数strcmp调用

if(((strcmp(t, preT) == 0) && (strcmp(s, preS) == 0)) || (((strcmp(t, preT) != 0) && (strcmp(s, preS) != 0))))

至少没有意义,因为tpreT指向的字符串具有不同的长度。 所以这个表达式strcmp(t, preT) == 0将始终评估为逻辑假。

我可以建议以下演示程序中显示的以下函数定义。

#include <stdio.h>
#include <string.h>
#include <stdbool.h>

bool isIsomorphic( const char *s, const char *t )
{
    size_t n = strlen( s );

    bool isomorphic = n == strlen( t );
    
    while ( isomorphic && n-- )
    {
        const char *p1 = strchr( s + n + 1, s[n] );
        const char *p2 = strchr( t + n + 1, t[n] );
        
        isomorphic = ( !p1 && !p2 ) || ( p1 && p2 && p1 - s == p2 - t );  
    }
    
    return isomorphic;
}

int main(void) 
{
    const char *s = "egg";
    const char *t = "add";
    
    printf( "\"%s\" is isomorphic with \"%s\" is %s\n", 
            s, t, isIsomorphic( s, t ) ? "true" : "false" );
    
    s = "foo";
    t = "bar";
    
    printf( "\"%s\" is isomorphic with \"%s\" is %s\n", 
            s, t, isIsomorphic( s, t ) ? "true" : "false" );
    
    s = "paper";
    t = "title";
    
    printf( "\"%s\" is isomorphic with \"%s\" is %s\n", 
            s, t, isIsomorphic( s, t ) ? "true" : "false" );
    
    s = "0123456789";
    t = "9876543210";
    
    printf( "\"%s\" is isomorphic with \"%s\" is %s\n", 
            s, t, isIsomorphic( s, t ) ? "true" : "false" );
    
    return 0;
}

程序输出是

"egg" is isomorphic with "add" is true
"foo" is isomorphic with "bar" is false
"paper" is isomorphic with "title" is true
"0123456789" is isomorphic with "9876543210" is true

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM