при печати символа* в C печатается только первый символ

#c #substring #dynamic-memory-allocation #c-strings #function-definition

Вопрос:

Я пытаюсь написать функцию, которая будет выводить подстроку строки, однако при ее печати печатается только первый символ в массиве.

Как вы можете видеть в коде, я вставил 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] = '';
    printf("%sn", str);
    free(str);
    return (str);
}

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

    printf("%sn", amp;sub);
    return (0);

}
 

Комментарии:

1. free(str); return (str); Возвращение освобожденной памяти добром не закончится. Удалите free его и предоставьте это делать вызывающему абоненту.

2. char sub; должно быть char *sub; и printf("%sn", amp;sub); должно быть printf("%sn", sub); , что есть char *sub = ft_substr(hello, 1, 4); printf("%sn", sub);

3. спасибо за совет относительно освобожденной памяти.

4. Я попытался добавить * в sub, но получил предупреждение об ошибке: несовместимое преобразование целого числа в указатель, инициализирующее «символ *» с выражением типа «символ»; удалить * [-Wint-преобразование] символ *sub = *ft_substr(привет, 1, 4);

Ответ №1:

Перед возвращением указателя str из функции вы освободили всю выделенную память

 free(str);
return (str);
 

Таким образом, возвращенный указатель является недопустимым.

Удалите заявление

 free(str);
 

Еще одна проблема в функции заключается в использовании неправильного индекса в этом операторе

 str[j   1] = '';
 

Просто напиши

 str[j] = '';
 

Также это заявление неверно

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

Он объявляет один символ, в то время как вам нужно объявить указатель, который будет указывать на динамически выделяемую строку в функции. Так что пишите

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

а потом напиши

 printf("%sn", 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] = '';
    }
    
    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] = '';
        }
    }
    
    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("%sn", sub?sub:"");
    free(sub);
    return (0);

}