【问题标题】:when printing a char* in C only the first character is being printed在 C 中打印 char* 时,仅打印第一个字符
【发布时间】:2021-11-01 08:37:16
【问题描述】:

我正在尝试编写一个函数来打印字符串的子字符串,但是在打印它时,只打印数组中的第一个字符。

正如您在代码中看到的那样,在创建子字符串并正确显示后,我在函数中添加了 printf 语句。然而,当函数被传递到主函数中的printf 函数时,它只打印第一个字符。

感谢人们能够提供的任何帮助。

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

char *ft_substr (const char *s, unsigned int start, size_t len)
{
    char        *str;
    unsigned int    i;
    unsigned int    j;

    str = malloc(len * sizeof(char) + 1);
    i = start;
    j = 0;
    while (i < len + start)
    {
        str[j] = s[i];
        j++;
        i++;
    }
    str[j + 1] = '\0';
    printf("%s\n", str);
    free(str);
    return (str);
}

int main (void)
{
    char hello[] = "Hello World";
    char sub = *ft_substr(hello, 1, 4);

    printf("%s\n", &sub);
    return (0);

}

【问题讨论】:

  • free(str); return (str); 返回释放的内存不会有好的结果。删除 free 并将其留给调用者执行此操作。
  • char sub; 应该是 char *sub;printf("%s\n", &amp;sub); 应该是 printf("%s\n", sub);char *sub = ft_substr(hello, 1, 4); printf("%s\n", sub);
  • 感谢有关释放内存的建议。
  • 我尝试将 * 添加到 sub 但我收到错误警告:incompatible integer to pointer conversion initializing 'char *' with an expression of type 'char'; remove * [-Wint-conversion] char *sub = *ft_substr(hello, 1, 4);

标签: c substring dynamic-memory-allocation c-strings function-definition


【解决方案1】:

在从函数返回指针 str 之前,您释放了所有分配的内存

free(str);
return (str);

所以返回的指针是无效的。

删除声明

free(str);

函数中的另一个问题是在此语句中使用了不正确的索引

str[j + 1] = '\0';

随便写

str[j] = '\0';

这个声明也不正确

char sub = *ft_substr(hello, 1, 4);

它声明了一个字符,而您需要声明一个指向函数中动态分配的字符串的指针。所以写

char *sub = ft_substr(hello, 1, 4);

然后写

printf("%s\n", sub);

free( sub );

如果您使用size_t 类型作为字符串的长度,那么也使用size_t 类型的索引。

这是一个演示程序。

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

char * ft_substr( const char *s, size_t start, size_t len )
{
    char *str = malloc( len + 1 );
    
    if ( str != NULL )
    {
        size_t i = 0;
        for ( ; i < len; i++ )
        {
            str[i] = s[start + i];
        }
        
        str[i] = '\0';
    }
    
    return str;
}

int main(void) 
{
    const char *hello= "Hello World";
    
    char *sub = ft_substr( hello, 1, 4 );

    if ( sub != NULL ) puts( sub );
    
    free( sub );
    
    return 0;
}

它的输出是

ello

如果函数会检查起始索引和长度是否指定正确,该函数会更安全。例如

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

char * ft_substr( const char *s, size_t start, size_t len )
{
    char *str = NULL;
    
    size_t n = strlen( s );
    
    if ( start < n )
    {
        if ( n - start < len ) len = n - start;
    
        str = malloc( len + 1 );
    
        if ( str )
        {
            memcpy( str, s + start, len );
            str[len] = '\0';
        }
    }
    
    return str;
}

int main(void) 
{
    const char *hello= "Hello World";
    
    char *sub = ft_substr( hello, 1, 4 );

    if ( sub != NULL ) puts( sub );
    
    free( sub );
    
    return 0;
}

【讨论】:

    【解决方案2】:

    您的主目录中有 UB。您尝试将单个字符打印为字符串(作为参考传递)。

    int main (void)
    {
        char hello[] = "Hello World";
        char *sub = ft_substr(hello, 1, 4);
    
        printf("%s\n", sub?sub:"");
        free(sub);
        return (0);
    
    }
    

    【讨论】:

      猜你喜欢
      • 2021-01-13
      • 1970-01-01
      • 2013-02-08
      • 1970-01-01
      • 2021-05-11
      • 1970-01-01
      • 2016-02-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多