【问题标题】:Concatenating two strings but getting null. please pont me error in this连接两个字符串但为空。请告诉我这个错误
【发布时间】:2021-08-28 13:08:02
【问题描述】:

我正在尝试将两个字符串复制到一个新指针。这是将字符串指针与子指针连接起来。试图在新指针 str 中输出。这有什么问题?

void addsubstring( char* string,  char* sub)
{
    //int m = strlen(string);
    char *str=(char*)malloc(sizeof(char)*10);
    int n =0;
    while( *string != '\0')
    {
        *(str) = *(string++);
        printf("char is %c\n", str[n++]);
        str++;
    }
        while( *sub != '\0')
    {
        *(str) = *(sub++);
        printf("char is %c\n", str[n++]);
        str++;``
    }
    printf("%s", str);
}

【问题讨论】:

  • str 指向字符串的结尾,而不是开头。此外,您从未添加空终止符。
  • 请确保生成的字符串少于 10 个字符,否则会发生超出范围的访问。
  • 这是buffer overflow 漏洞的优秀概念验证代码。请不要在生产中使用它,否则会发生不好的事情。

标签: c while-loop c-strings string-concatenation function-definition


【解决方案1】:

对于初学者来说,使用幻数 10 分配内存会使函数不安全。

char *str=(char*)malloc(sizeof(char)*10);

在这些while循环中

while( *string != '\0')
{
    *(str) = *(string++);
    printf("char is %c\n", str[n++]);
    str++;
}
    while( *sub != '\0')
{
    *(str) = *(sub++);
    printf("char is %c\n", str[n++]);
    str++;``
}

指针str 正在更改(递增)。所以在循环之后它指向一个垃圾。

您忘记在结果字符串中包含终止零字符'\0'

函数可以通过以下方式定义

char * addsubstring( const char *s1,  const char *s2 )
{
    size_t n1 = strlen( s1 );
    char *result = malloc( n1 + strlen( s2 ) + 1 );

    if ( result != NULL )
    {
        memcpy( result, s1, n1 );
        strcpy( result + n1, s2 );
    }

    return result;
}

这是一个演示程序

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

char * addsubstring( const char *s1,  const char *s2 )
{
    size_t n1 = strlen( s1 );
    char *result = malloc( n1 + strlen( s2 ) + 1 );

    if ( result != NULL )
    {
        memcpy( result, s1, n1 );
        strcpy( result + n1, s2 );
    }

    return result;
}

int main(void) 
{
    char *p = addsubstring( "Hello ", "World!" );
    
    if ( p ) puts( p );
    
    free( p );
    
    return 0;
}

程序输出是

Hello World!

如果您可能不使用标准的 C 字符串函数,则可以定义该函数,如下面的演示程序所示

#include <stdio.h>
#include <stdlib.h>

char * addsubstring( const char *s1,  const char *s2 )
{
    size_t n = 0;
    
    while ( s1[n] ) ++n;
    while ( s2[n] ) ++n;
    
    char *result = malloc( n + 1 );

    if ( result != NULL )
    {
        char *p = result;
        while ( *s1 ) *p++ = *s1++;
        
        while ( ( *p++ = *s2++ ) );
    }

    return result;
}

int main(void) 
{
    char *p = addsubstring( "Hello ", "World!" );
    
    if ( p ) puts( p );
    
    free( p );
    
    return 0;
}

程序输出同上图

Hello World!

【讨论】:

  • 旁白:很好奇代码使用memcpy( result, s1, n1 ); strcpy( result + n1, s2 );。我本来期望 2 strcpy(),或者更好的 2 memcpy()。对齐优化?
  • @chux-ReinstateMonica strcpy 的效率低于 memcpy。它可以使用两个 memcpy 编写。 U 在答案中使用了该方法,因为我只想知道第一次复制后目标字符串中的偏移量。
【解决方案2】:

问题是指针str 滑动了。您应该创建另一个指针以用作原点。此外,您还必须通过添加空字符来终止搅拌,然后再将其传递给 %s

也不要忘记释放分配的缓冲区,否则会发生内存泄漏。

还有一点,malloc()family 的转换结果是considered as a bad practice

固定代码:

void addsubstring( char* string,  char* sub)
{
    //int m = strlen(string);
    char *str=malloc(sizeof(char)*10);
    char *str_start = str;
    int n =0;
    while( *string != '\0')
    {
        *(str) = *(string++);
        printf("char is %c\n", str_start[n++]);
        str++;
    }
        while( *sub != '\0')
    {
        *(str) = *(sub++);
        printf("char is %c\n", str_start[n++]);
        str++;
    }
    *(str) = '\0';
    printf("%s", str_start);
    free(str_start);
}

【讨论】:

  • 能否请您告诉我为什么 str 不起作用以及需要 bew 指针
猜你喜欢
  • 2022-08-16
  • 1970-01-01
  • 1970-01-01
  • 2021-09-26
  • 2012-12-22
  • 1970-01-01
  • 2016-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多