我有一个递归地对一组数字进行一些计算的函数。我还希望通过传递前一次计算中的字符串并将其与当前操作连接来在每次递归调用中打印计算。示例输出可能如下所示:
3
(3) + 2
((3) + 2) / 4
(((3) + 2) / 4) x 5
((((3) + 2) / 4) x 5) + 14
... and so on
所以基本上,第二个调用得到3并且向它追加+ 2,第三个调用被传递(3)+ 2等等。我的递归函数原型看起来像这样:
void calc_rec(int input[], int length, char * previous_string);
我写了一个2个辅助函数来帮助我进行操作,但是当我测试它们时它们会崩溃:
/**********************************************************************
* dynamically allocate and append new string to old string and return a pointer to it
**********************************************************************/
char * strapp(char * old, char * new)
{
// find the size of the string to allocate
int len = sizeof(char) * (strlen(old) + strlen(new));
// allocate a pointer to the new string
char * out = (char*)malloc(len);
// concat both strings and return
sprintf(out, "%s%s", old, new);
return out;
}
/**********************************************************************
* returns a pretty math representation of the calculation op
**********************************************************************/
char * mathop(char * old, char operand, int num)
{
char * output, *newout;
char fstr[50]; // random guess.. couldn't think of a better way.
sprintf(fstr, " %c %d", operand, num);
output = strapp(old, fstr);
newout = (char*)malloc( 2*sizeof(char)+sizeof(output) );
sprintf(newout, "(%s)", output);
free(output);
return newout;
}
void test_mathop()
{
int i, total = 10;
char * first = "3";
printf("in test_mathop\n");
while (i < total)
{
first = mathop(first, "+", i);
printf("%s\n", first);
++i;
}
}
strapp()返回一个指向新附加字符串(工作)的指针,mathop()应该使用旧计算字符串(“(3)+2”),一个字符操作数('+',' - '等等)和一个int,并返回一个指向新字符串的指针,例如“((3)+2)/ 3”。知道我搞砸了什么吗?感谢。
答案 0 :(得分:4)
您应该为终止0分配一个额外的字节。
你应该在这里使用strlen
代替sizeof
:
newout = (char*)malloc( 2*sizeof(char)+sizeof(output) );
Sizeof返回char*
的大小(在平均系统上大小为4),而不是output
指向的字符串的长度。
此外,正如@Agnel正确指出的那样,i
未初始化,虽然这不会导致程序崩溃,但只需执行循环一次。
此外,我建议 strstr
strcat
来连接字符串。
答案 1 :(得分:2)
我能看到的一个直接问题是:
int len = sizeof(char) * (strlen(old) + strlen(new));
最后没有为NULL
char分配空间。所以你需要分配一个额外的char。
答案 2 :(得分:2)
首先尝试这个:
char * append_strings(const char * old, const char * new)
{
// find the size of the string to allocate
size_t len = strlen(old) + strlen(new) + 1;
// allocate a pointer to the new string
char *out = malloc(len);
// concat both strings and return
sprintf(out, "%s%s", old, new);
return out;
}
这只是您的代码,有许多修复:
const
。size_t
类型的变量中。sizeof (char)
删除了不必要的缩放。malloc()
。str
开头的函数,即保留空格。评论者指出,谢谢!对于性能,您可以利用这两个输入上的strlen()
调用这一事实,并避免使用sprintf()
:
char * append_strings(const char * old, const char * new)
{
// find the size of the string to allocate
const size_t old_len = strlen(old), new_len = strlen(new);
const size_t out_len = old_len + new_len + 1;
// allocate a pointer to the new string
char *out = malloc(out_len);
// concat both strings and return
memcpy(out, old, old_len);
memcpy(out + old_len, new, new_len + 1);
return out;
}
这应该更快一些,但我没有对它进行基准测试。请注意最终memcpy()
如何包含new
字符串中的终结符,因此无需手动设置它。
答案 3 :(得分:0)
感谢所有回复,他们非常有帮助 - 尤其是strcat建议,并发现我需要为'\ 0'字符分配空间。我最终使用realloc来“拉伸”字符串并附加前导和尾随字符。我还删除了strapp(append_strings)函数,并将其全部用于mathop。方法如下:
/**********************************************************************
* returns a pretty math representation of the calculation op
**********************************************************************/
char * mathop(char * previous, char operand, float num)
{
char *output, *temp, calculation[50];
size_t newlen;
// copy the previous data into the temp string
temp = (char*)malloc( strlen(previous) + 1 );
output = (char*)malloc(2);
strcpy(temp, previous);
strcpy(output, "(\0");
// create the string portion to append to the output
sprintf(calculation, " %c %.1f)\0", operand, num);
// reallocate the output to append the additional string
newlen = strlen(temp) + strlen(calculation) + 1;
temp = realloc(temp, newlen);
// append the new data to output
strcat(temp, calculation);
output = realloc(output, strlen(temp) + 2);
strcat(output, temp);
printf("%s\n", output);
free(temp);
return output;
}
再次感谢!