【发布时间】:2016-02-25 07:41:21
【问题描述】:
我正在制作一个类似于 printf 的函数,它需要接受一个字符串和如下参数:
form("Integer %d, String %s", 54, "STRING");
并创建一个字符串"Integer 54, String STRING"。
我正在使用stdarg.h 库,因为我的函数需要根据字符串具有可变数量的参数。
问题是我收到了Segmentation fault。我发现只有当我使用传递给va_arg 的字符串(char*) 执行strlen 或strcpy 时才会发生这种情况。这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
char* form(char *format, ...)
{
va_list ap;char sign;int br=0,lasti,memo=0;char* help;
int ints; float floats; double doubles; char chars; char* strings;
va_start(ap,format);
char* result=(char*)calloc(100,strlen(format));
strcpy(result,format);
for(int i=0; result[i] ;i++)
if(result[i]=='%')
{
switch (result[i+1])
{
case 'd': {
ints=va_arg(ap,int);
int b,save=ints,dec=1,j;char *p=result+i;
for(b=0;save;b++) {save/=10;dec*=10;}
for(dec/=10,j=0; dec ; j++) { p[j]=((ints/dec)%10)+0x30; dec/=10; }
strcpy(result+i+b,format+i-memo+2);memo+=b-2;
} break;
case 'f': {
floats=va_arg(ap,double);
} break;
case 'l': {
doubles=va_arg(ap,double);
} break;
case 'c': {
chars=va_arg(ap,int);
result[i]=chars;
} break;
case 's': {
strings=va_arg(ap,char*);
strcpy(result+i+strlen(strings),format+i-memo+2);memo+=(strlen(strings)-2);
} break;
default: printf("Unknown type.\n"); break;
}
i=0;
}
return result;
}
int main()
{
char a[100];
scanf("%s",a);
char*s=form("treci %s peti",a);
printf("%s", s);
printf("\n");
free(s);
return 0;
}
strlen 或 strcpy 可能导致段错误的唯一方法是字符串不是以 null 结尾的,但我的是。那么这里出了什么问题,我该如何解决呢?
编辑:添加代码。
【问题讨论】:
-
您能尝试创建一个Minimal, Complete, and Verifiable Example 并展示给我们看吗?或者至少向我们展示
form函数的大部分内容?我们确实需要查看变量声明、定义和初始化等内容。 -
还有你不使用的原因吗?
vsnprintf格式化字符串?您可以让它告诉您它需要的确切长度,因此您可以在需要时为字符串动态分配内存。 If 还会为您提供所有标准格式,包括您不处理的格式、字段宽度等。 -
我的课程中还没有学习 vsnprintf。
-
if(result[i]=='%')末尾的i=0不正确。 -
strcpy电话看起来可能是嫌疑人。尝试改为例如memcpy(result + i, strings, strlen(strings)); strcpy(result + i + strlen(strings), format + i + 2);
标签: c string segmentation-fault variadic-functions