C 如何将字符串返回给另一个函数?
我正在编写一个函数,它根据用户的选择在右边或左边填充几个字符。我使用strcat函数将字符合并到字符串中,在使用右填充的情况下效果很好,但在使用左填充的情况下,我得到了垃圾字符,因此我编写了自己的concat函数。仍然是相同的结果,请参见下面的代码C 如何将字符串返回给另一个函数?,c,C,我正在编写一个函数,它根据用户的选择在右边或左边填充几个字符。我使用strcat函数将字符合并到字符串中,在使用右填充的情况下效果很好,但在使用左填充的情况下,我得到了垃圾字符,因此我编写了自己的concat函数。仍然是相同的结果,请参见下面的代码 char *concat(char a[], char b[]) { int len1=0, len2=0, i, j; char tmp[100], *tmp2; trace("concat(): Begin");
char *concat(char a[], char b[])
{
int len1=0, len2=0, i, j;
char tmp[100], *tmp2;
trace("concat(): Begin");
len1 = strlen(a);
len2 = strlen(b);
for(i=0, j=0; i<(len1+len2); i++)
{
if(i<len1)
tmp[i]=a[i];
else
tmp[i]=b[j++];
}
tmp[i]='\0';
tmp2 = tmp;
sprintf(str, "Concatenated String: %s", tmp2);
trace(str);
trace("concat(): End");
return tmp2;
}
char *pad(char *field_name, char *field_val)
{
char *temp_var=field_val, *temp_var2;
int i=0;
char pad_var[100];
trace("pad(): Begin");
sprintf(str, "field name to search for: %s and field value to be formatted: %s", field_name, field_val);
trace(str);
get_format_vars(field_name);
sprintf(str, "strlen(field_val) = %d and len = %d", strlen(field_val), len);
trace(str);
if(strlen(field_val)<len)
{
trace("Data should be Padded");
trace(field_val);
for(i=0; i<len-strlen(field_val); i++)
{
pad_var[i] = pc;
}
pad_var[i]='\0';
sprintf(str, "pad_var = %s", pad_var);
trace(str);
switch(pd)
{
case 'l':
case 'L':
sprintf(str, "length of field: ", strlen(field_val));
temp_var = concat(pad_var, field_val);
sprintf(str, "Value after left padding: (%.*s)", len, temp_var);
trace(str);
break;
case 'r':
case 'R':
strcat(field_val, pad_var);
temp_var = field_val;
sprintf(str, "Value after right padding: (%s)", temp_var);
trace(str);
break;
case 'n':
case 'N':
trace("No formatting to be done for this field");
break;
default:
trace("Wrong value for padding type.");
}
trace("Data Padded");
}
else
{
trace("Field length already equal to format length");
}
temp_var2 = temp_var;
sprintf(str, "Data after/without formatting: (%s)", temp_var2);
trace(str);
trace("pad(): End");
return temp_var;
}
char*concat(char a[],char b[]
{
int len1=0,len2=0,i,j;
char-tmp[100],*tmp2;
跟踪(“concat():Begin”);
len1=strlen(a);
len2=strlen(b);
对于(i=0,j=0;i您返回一个指向临时堆栈变量的指针,该变量在函数退出时超出范围。它的内存可能(将)被其他函数调用重用。最简单的修复方法是在concat
中动态分配内存,然后在调用程序中释放它
char* tmp = malloc(len1+len2+1);
您还可以将concat
函数简化为
char* tmp = malloc(len1+len2+1);
strcpy(tmp, a);
strcat(tmp, b);
return tmp;
您正在返回一个指向临时堆栈变量的指针,该变量在函数退出时超出范围。它的内存可能(将)被其他函数调用重用。最简单的修复方法是在concat
中动态分配内存,然后在调用者中释放它
char* tmp = malloc(len1+len2+1);
您还可以将concat
函数简化为
char* tmp = malloc(len1+len2+1);
strcpy(tmp, a);
strcat(tmp, b);
return tmp;
在返回函数内的堆栈上分配返回的结果:
char tmp[100]
这甚至可以实际工作(通常的“经典”堆栈的内容不会因返回而中断),但前提是您在其他地方立即使用或复制返回的字符串,而不进行另一次调用。一旦您进行第二次调用(包括系统调用),堆栈将被重用,您将得到垃圾
在返回之前将引用赋值给另一个变量无效
使用其中一个系列函数返回克隆副本(不再需要时不要忘记释放)。您可以在返回函数的堆栈中分配返回的结果:
char tmp[100]
这甚至可以实际工作(通常的“经典”堆栈的内容不会因返回而中断),但前提是您在其他地方立即使用或复制返回的字符串,而不进行另一次调用。一旦您进行第二次调用(包括系统调用),堆栈将被重用,您将得到垃圾
在返回之前将引用赋值给另一个变量无效
使用其中一个系列函数返回克隆副本(不再需要时不要忘记释放)
您不应该编写自己版本的strcat
您不应该返回自动(本地)数组-在函数返回后,使用它调用未定义的行为,该数组超出范围
要么malloc()
占用一些内存并返回动态分配的块或内存,要么使用输入/输出参数调用函数,该参数是调用方中声明的数组(与被调用方相反)
您不应该编写自己版本的strcat
您不应该返回自动(本地)数组-在函数返回后,使用它调用未定义的行为,该数组超出范围
malloc()
占用一些内存并返回动态分配的块或内存,或者使用输入/输出参数调用函数,该参数是调用方中声明的数组(与被调用方相反).您是否在调试器中跟踪/查看了它,以查看问题开始的时间/地点?修复缩进的可能重复,这是不可读的。您是否在调试器中跟踪/查看了它,以查看问题开始的时间/地点?修复缩进的可能重复,这是不可读的。堆栈内容通常不会通过返回来修改从函数返回。仅当堆栈再次用于进行第二次调用时,该值才会丢失。@AudriusMeškauskas不推测。UB为UB。通常不会通过从函数返回来修改堆栈内容。仅当堆栈再次用于进行第二次调用时,该值才会丢失。@AudriusMeškauskas不推测。UB为UB。谢谢。它将标记,但我不明白的是,当我使用strcat作为左填充时,它为什么不起作用,而在右填充时却起作用。很高兴你已经起作用了。恐怕我不完全理解你的问题。strcat
在dest字符串中查找空终止符,并在此时追加src字符串。如果你有足够的y以“padding”字节开头的大型dest字符串,可以使用strcat(dest,src)
谢谢。它起作用了,但我不明白的是,当我在左填充中使用strcat时,为什么它不起作用,而在右填充中使用它。很高兴你能这样做。恐怕我不完全理解你的问题。strcat
在dest字符串中查找空终止符,并在这一点上附加一个src字符串。如果y如果您有一个足够大的dest字符串,它以“padding”字节开头,您可以使用strcat(dest,src)