#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);
}