如何判断是否将可选参数传递给函数C.

133*_*m3r 3 c substring variadic-functions p99

编辑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;
}
Run Code Online (Sandbox Code Playgroud)

基本上我想仍然能够不包括我想要的字符串的长度,只是让它到字符串的末尾.但我似乎找不到办法做到这一点.由于也无法知道在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;
}
Run Code Online (Sandbox Code Playgroud)

然后在一个文件中我调用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;
}
Run Code Online (Sandbox Code Playgroud)

functions.c有一个包含for 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__)
Run Code Online (Sandbox Code Playgroud)

海湾合作委员会只是说对象不是一个功能

编辑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;
}
Run Code Online (Sandbox Code Playgroud)

你需要从那里获得p99.这是由选定的答案.只需进入您的源目录,您就可以了.还要总结他对许可证的回答.你可以随意使用它,但基本上你不能分叉它.因此,为此目的,您可以在任何项目中使用它和字符串函数,无论是专有还是开源.

我唯一要问的是你至少要给这个帖子一个链接,以便发生在它上面的其他人可以了解堆栈溢出,因为这就是我对我在这里得到帮助的事情的评论.

Wil*_*and 6

在C中,没有可选参数这样的东西.这种情况的常见习语是要么具有两个功能; substr(char *, size_t start, size_t end)和/ substr_f(char *, size_t start)或具有单个函数,其中end,如果给定特殊值,将具有特殊含义(例如在这种情况下,可能是小于start的任何数字,或者简单地为0).

使用varargs时,您需要在参数列表的末尾使用sentinel值(例如NULL),或者作为argc(参数计数)的早期参数传入.

C具有非常少量的运行时内省,这是一个功能,而不是错误.

编辑:在相关说明中,用于字符串长度和C中的偏移的正确类型是size_t.它是唯一保证足够大以解决任何字符串中的任何字符的整数类型,并且保证小到足以在存储时不浪费空间.

另请注意,它是未签名的.