(C)函数的返回值是否被误解?

wkyowqbh  于 2023-04-11  发布在  其他
关注(0)|答案(2)|浏览(111)

(编辑)
在C中更新和返回一个字符串时可能会产生误解。
我是一名学生,刚刚开始尝试动态内存分配技术。最近,我被告知要处理一个字符串copy()函数,类似于C中的strcpy()函数<string.h>。
它应该接受两个参数:char c1[],char c2[].目前,我关注的是一个约束,其中字符串c1的长度小于字符串c2.这种情况下,我们将复制一个较大的字符串到一个较小的字符串.所以,自然会扩大前一个字符串的大小. (我已经定义了一个函数len()返回字符串的长度.它工作正常)
验证码:

char* copy(char c1[],char c2[])
{
    int i=0;
    int lc1=len(c1);
    int lc2=len(c2);
    if(lc1<lc2)
    {
                //are the following two lines allowed?
        c1=(char*) malloc(lc1*sizeof(char));
        c1=(char*) realloc(c1,lc2*sizeof(char));
        for(i=0;i<lc2;i++)
        {
            *(c1+i)=c2[i];
        }
        *(c1+lc2)='\0';
    }
    return c1;
}
  • 如果这段代码有多个问题,我不会感到惊讶!* 我试着测试它如下:
#include <stdio.h>
#include <string.h>
#include "mystring.h"
main()
{
    int i;
    char s1[12],s2[12];
    gets(s1);
    gets(s2);
    printf("copy: %s",copy(s1,s2));
    printf("\ns1: %s",s1);
}

我得到:output
我希望两个输出都是一样的,即copy和s1。碰巧只有当我把它沿着调用一起打印出来的时候,它才能起作用。我希望在打印s1的时候,它能打印出copy。
我在哪里出错了?我认为这与我正在处理的变量的作用域有关,或者是指针和内存分配作为一个整体!

**EDIT:**我做了一个alternative-function xcopy:

char* xcopy(char c1[])
{
    int i=0;
    int lc1=len(c1);
    char* c2=(char*) malloc((lc1+1)*sizeof(char));
    for(i=0;i<lc1;i++)
    {
        *(c2+i)=c1[i];
    }
    *(c2+lc1)='\0';
    return c2;
}

我意识到这个函数并没有解决实际问题。

感谢您的帮助!

f5emj3cl

f5emj3cl1#

函数copy没有意义。
对于初学者来说,参数c1指向的数组不一定包含字符串。

int lc1=len(c1);

调用未定义的行为。
即使指针c1指向的数组包含一个字符串,存储的字符串也可以比数组的大小小得多。

int lc1=len(c1);

使用以下if语句

if(lc1<lc2)

这说不通
也分配内存两次

c1=(char*) malloc(lc1*sizeof(char));
c1=(char*) realloc(c1,lc2*sizeof(char));

是不安全的、多余的和低效的。
实际上,该函数不会复制目标数组中指针c2所指向的字符串。因此再次使用参数c1没有意义。如果删除第一个无意义的参数,您的函数看起来像POSIX函数strdup
您没有展示如何计算字符串长度的函数len,但它似乎不计算字符串的终止零字符。在这种情况下,您至少需要使用表达式( lc2 + 1 ) * sizeof( char )分配内存,以保留终止零字符'\0'的内存。否则,此语句

*(c1+lc2)='\0';

调用未定义的行为。
函数的用户有责任提供一个足够大的目标数组来存储源字符串。函数不应分配任何内存。
通过与标准C函数strcpy类比,该函数可以如下所示

char * copy( char s1[], const char s2[] )
{
    for ( char *p = s1; ( *p++ = *s2++ ) != '\0'; );

    return s1;
}

请注意,函数gets是不安全的,并且不受C标准支持。请使用标准C函数fgets。它可以附加一个带有新行字符'\n'的字符串。
要删除它,您可以编写例如

c2[ strcspn( c2, "\n" ) ] = '\0';
ar5n3qh5

ar5n3qh52#

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

/* headers.h
#define SLEN 100
#define SLENT 200

typedef struct size {
    size_t length_one[SLEN];
    size_t length_two[SLENT];

} siz, *siz_point;

char * copy(char var1[], char var2[])
{
    struct size siz;
    int i = 0;

    siz.length_one = strlen(var1);
    siz.length_two = strlen(var2);

    if (siz.length_one < siz.length_two) {

        void vars_one = (char *) malloc(siz.length_one * sizeof(siz.length_one));
        void vars_two = (char *) memcpy(siz.length_one, siz.length_two, size_t memory);

        for (i=0; i < siz.length_two; i++) {
            *(var1+i) = var2[i];
        }
        *(var1 + siz.length_two) = '\0';
    }
    return var1;
}

*/

#define LEN 20

char * s_gets(char * set_string, size_t isize_n);

char * s_gets(char * set_string, size_t isize_n) {
    char * retnval;
    char * findval;

    retnval = fgets(set_string, isize_n, stdin);
    if (retnval) {
        findval = strchr(set_string, '\n');
        if (findval) *findval = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    return retnval;
}

int
main() {

    int i;
    char string_one[LEN];
    char string_two[LEN];

    s_gets(string_one, "This string one");
    s_gets(string_two, "This string two");

    printf("Copying string: %s", copy(string_one, string_two));
    printf("\nString: %s", string_one);
}

也许你的代码看起来像这样

相关问题