У вас есть четыре проблемы:
строка, возвращаемая term_to_string
, не заканчивается символом с кодом 0, поэтому каждый printf для записи результата выходит из выделенного массива с неопределенным поведением
неправильный способ вставки внешнего представления целочисленного значения, например, для выполнения *ptr = term->coefficient
просто установите один символ с кодом term->coefficient
cast (усеченный) на char
неправильные способы вычисления размера выделенной строки, размер внешнего представления int не задается sizeof
ваша инициализация структуры неверна, второе значение ('x') является явно символом, но вы инициализируете коэффициент с ним, вам нужно соблюдать порядок полей.
Если {3, 'x', 2};
должен выдать 3x^2
, это означает, что первое поле struct должно быть коэффициент (вместо показатель ), второе должно быть var (вместо коэффициент ), а третье должно быть показатель (вместо var ). Или, не изменяя определение struct , вы должны изменить порядок инициализации, чтобы иметь term_t testterm3 = {2, 3, 'x'};
.
Также {1, 'x', 0}
не может выдавать «x», оно должно выдавать «1» или «0»
Без изменения определения struct и добавления особых случаев, которыми вы не управляли, предложение может быть:
#include <stdio.h>
#include <malloc.h>
typedef struct term
{
int exponent, coefficient;
char var;
} term_t;
int snprintf(char *str, size_t size, const char *format, ...);
char *term_to_string(const term_t *term)
{
char *ptr;
if ((term->exponent == 0) || (term->coefficient == 0))
{
ptr = malloc(snprintf(NULL, 0, "%d", term->coefficient) + 1); /* +1 for char \0 */
sprintf(ptr, "%d", term->coefficient);
}
else if (term->coefficient == 1)
{
if (term->exponent == 1)
{
ptr = malloc(2);
ptr[0] = term->var;
ptr[1] = 0;
}
else
{
ptr = malloc(snprintf(NULL, 0, "%d", term->exponent) + 3); /* +3 for var and ^ and char \0 */
sprintf(ptr, "%c^%d", term->var, term->exponent);
}
}
else if (term->coefficient == -1)
{
if (term->exponent == 1)
{
ptr = malloc(3);
ptr[0] = '-';
ptr[1] = term->var;
ptr[2] = 0;
}
else
{
ptr = malloc(snprintf(NULL, 0, "%d", term->exponent) + 4); /* +4 for - and var and ^ and char \0 */
sprintf(ptr, "-%c^%d", term->var, term->exponent);
}
}
else if (term->exponent == 1)
{
ptr = malloc(snprintf(NULL, 0, "%d", term->coefficient) + 2); /* +2 for var and char \0 */
sprintf(ptr, "%d%c", term->coefficient, term->var);
}
else
{
ptr = malloc(snprintf(NULL, 0, "%d%d", term->exponent, term->coefficient) + 3); /* +3 for var and ^ and char \0 */
sprintf(ptr, "%d%c^%d", term->coefficient, term->var, term->exponent);
}
return ptr;
}
int main()
{
term_t test[] = {
{0, 1, 'x'},
{1, 0, 'x'},
{1, 1, 'x'},
{1, -1, 'x'},
{1, 2, 'x'},
{2, 1, 'x'},
{2, -1, 'x'},
{2, 3, 'x'}
};
for (int i = 0; i != sizeof(test)/sizeof(term_t); ++i) {
char * s = term_to_string(&test[i]);
printf("test {exp=%d, coef=%d, var='%c'} : %s\n",
test[i].exponent, test[i].coefficient, test[i].var, s);
free(s);
}
return 0;
}
Компиляция и исполнение:
pi@raspberrypi:/tmp $ gcc -pedantic -Wall -Wextra e.c
pi@raspberrypi:/tmp $ ./a.out
test {exp=0, coef=1, var='x'} : 1
test {exp=1, coef=0, var='x'} : 0
test {exp=1, coef=1, var='x'} : x
test {exp=1, coef=-1, var='x'} : -x
test {exp=1, coef=2, var='x'} : 2x
test {exp=2, coef=1, var='x'} : x^2
test {exp=2, coef=-1, var='x'} : -x^2
test {exp=2, coef=3, var='x'} : 3x^2
pi@raspberrypi:/tmp $
Исполнение под valgrind :
pi@raspberrypi:/tmp $ valgrind ./a.out
==4285== Memcheck, a memory error detector
==4285== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4285== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==4285== Command: ./a.out
==4285==
test {exp=0, coef=1, var='x'} : 1
test {exp=1, coef=0, var='x'} : 0
test {exp=1, coef=1, var='x'} : x
test {exp=1, coef=-1, var='x'} : -x
test {exp=1, coef=2, var='x'} : 2x
test {exp=2, coef=1, var='x'} : x^2
test {exp=2, coef=-1, var='x'} : -x^2
test {exp=2, coef=3, var='x'} : 3x^2
==4285==
==4285== HEAP SUMMARY:
==4285== in use at exit: 0 bytes in 0 blocks
==4285== total heap usage: 9 allocs, 9 frees, 1,050 bytes allocated
==4285==
==4285== All heap blocks were freed -- no leaks are possible
==4285==
==4285== For counts of detected and suppressed errors, rerun with: -v
==4285== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
pi@raspberrypi:/tmp $