编辑3:若要查看完整代码,请参阅第一个答案或本帖的末尾。
正如标题所述,我正在尝试找到一种方法来判断函数是否传递了可选参数。我想做的是类似于几乎所有动态语言处理它们的子字符串函数的方式。以下是目前的代码,但它不起作用,因为我不知道何时使用/未使用该参数。
char *substring(char *string,unsigned int start, ...){
va_list args;
int unsigned i=0;
long end=-1;
long long length=strlen(string);
va_start(args,start);
end=va_arg(args,int);
va_end(args);
if(end==-1){
end=length;
}
char *to_string=malloc(end);
strncpy(to_string,string+start,end);
return to_string;
}
基本上,我希望仍然可以不包括我想要返回的字符串的长度,只需让它到达字符串的末尾。但我似乎找不到一种方法来实现这个功能。由于在 C 中没有办法知道传递的参数数量,所以这让我失去了第一个想法。
编辑: 这里是当前代码的新方法。
#define substring(...) P99_CALL_DEFARG(substring, 3, __VA_ARGS__)
#define substring_defarg_2 (0)
char *substring(char *string,unsigned int start, int end){
int unsigned i=0;
int num=0;
long long length=strlen(string);
if(end==0){
end=length;
}
char *to_string=malloc(length);
strncpy(to_string,string+start,end);
return to_string;
}
然后我在一个名为test.c的文件中调用它,以查看是否有效。
#include "functions.c"
int main(void){
printf("str:%s",substring("hello world",3,2));
printf("\nstr2:%s\n",substring("hello world",3));
return 0;
}
functions.c中包含了functions.h的头文件,该头文件包含了所有需要的内容。以下是clang输出(因为clang通常会提供更详细的信息)。
In file included from ./p99/p99.h:1307:
./p99/p99_generic.h:68:16: warning: '__error__' attribute ignored
__attribute__((__error__("Invalid choice in type generic expression")))
^
test.c:4:26: error: called object type 'int' is not a function or function
pointer
printf("\nstr2:%s\n",substring("hello world",3));
^~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from test.c:1:
In file included from ./functions.c:34:
In file included from ./functions.h:50:
./string.c:77:24: note: instantiated from:
#define substring(...) P99_CALL_DEFARG(substring, 3, __VA_ARGS__)
GCC只是说这个对象不是一个函数。
编辑2:请注意,将其设置为-1也不会改变它,它仍然会抛出相同的错误。我使用的编译选项如下。
gcc -std=c99 -c test.c -o test -lm -Wall
Clang也是同样的情况(它是否与之一起工作是另一个问题)。
回答在此处。
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include "p99/p99.h"
#define substring(...) P99_CALL_DEFARG(substring, 3, __VA_ARGS__)
#define substring_defarg_2() (-1)
char *substring(char *string, size_t start, size_t len) {
size_t length = strlen(string);
if(len == SIZE_MAX){
len = length - start;
}
char *to_string = malloc(len + 1);
memcpy(to_string, string+start, len);
to_string[len] = '\0';
return to_string;
}
你需要从这里获取p99。它是由选定的答案提供的。只需将其放入您的源目录中,您就可以使用了。此外,总结他在许可证方面的回答。您可以自由使用它,但基本上不能派生它。因此,为此目的,无论是专有项目还是开源项目,您都可以自由使用它和字符串函数。
我唯一要求的是,您至少要提供一个链接返回到这个线程,以便其他人能够了解stackoverflow,因为这是我对在这里获得帮助的事情进行评论的方式。
printf
使用格式字符串)。 - Jerry Coffin