我正在编写一个函数,该函数可以打印出来作为标准输出,就像常规printf函数一样,但是需要像%d或%s这样的指标,它需要{i}或{s}。我遇到的问题是,当格式参数的字符串太长约 23 个字符时,我在调用 vfprintf 函数的行出现分段错误。
int mr_asprintf(const char *format, ...)
{
int i;
char *newFormat = calloc(1,sizeof(char));
char integer[3] = "%d";
char str[3] = "%s";
char tmpStr[2];
va_list args;
newFormat[0] =' ';
tmpStr[1] = ' ';
for(i=0;format[i]!=' ';i++) // convert to printf syntaxe
{
if(format[i]=='{' && format[i+2]=='}') //check if it's {x}
{
switch(format[i+1])
{
case 'i':
strcat(newFormat,integer);
i += 2;
break;
case 's':
strcat(newFormat,str);
i += 2;
break;
}
}
else
{
tmpStr[0] = format[i];
strcat(newFormat,tmpStr);
}
}
va_start(args,format);
int s = vfprintf(stdout,newFormat,args);
va_end(args);
free(newFormat);
return s;
}
测试示例:
int main()
{
char *result = mr_asprintf("bce }edadacba{i}}aa}da{s}fe aeaee d{i}cefaa",55,"XXX",66);
printf("%sn",result);
return 0;
}
您的字符串newFormat
被分配为大小 1,并且您正在使用 strcat 附加到它 - 但 strcat 不做任何数组大小调整,因此newFormat
很快就会开始踩踏未分配的内存。输出字符串的长度将始终为 <= 输入字符串的长度,因此您可能应该分配该大小的字符串。
最后,虽然这不应该在 vprintf 中导致段错误,但它可能会导致以后出现意外行为 -
for(i=0;format[i]!=' ';i++) // convert to printf syntaxe
{
if(format[i]=='{' && format[i+2]=='}') //check if it's {x}
检查当前位置是否为字符串的末尾,然后检查当前位置后面的两个字符是否有右括号,而不检查字符串是否在下一个空格上结束。这可能会导致读取超出为阵列分配的内存。将 if 语句替换为 if(format[i]=='{' && (format[i+1]=='i' || format[i+1]=='s') && format[i+2]=='}')
可以避免此问题。