Eha*_*yed 5 c printf struct function-pointers variadic-functions
我创建了一个结构体,它将格式字符和指向根据格式化程序打印的函数的指针进行分组。
typedef struct formatter
{
char spec;
void (*print)(va_list);
} fmt;
Run Code Online (Sandbox Code Playgroud)
然后,我创建了打印每种格式的函数。
void print_char(va_list args)
{
printf("%c", va_arg(args, int));
}
void print_int(va_list args)
{
printf("%d", va_arg(args, int));
}
void print_float(va_list args)
{
printf("%f", va_arg(args, double));
}
void print_string(va_list args)
{
char *spec = va_arg(args, char *);
if (spec == NULL)
{
printf("(nil)");
return;
}
printf("%s", spec);
}
Run Code Online (Sandbox Code Playgroud)
在主可变参数函数中,我创建了一个结构数组以便对其进行循环。
void print_all(const char *const format, ...)
{
fmt f[] = {
{'c', print_char},
{'i', print_int},
{'f', print_float},
{'s', print_string},
{'\0', NULL}};
int i = 0, j;
char *separator = "";
va_list args;
va_start(args, format);
if (format == NULL)
{
return;
}
while (format[i] != '\0')
{
j = 0;
while (f[j].spec)
{
if (f[j].spec == format[i])
{
printf("%s", separator);
f[j].print(args);
separator = ", ";
break;
}
j++;
}
i++;
}
printf("\n");
va_end(args);
}
Run Code Online (Sandbox Code Playgroud)
当我编译程序并测试以下情况时,问题来了:
int main(void)
{
print_all("ceis", 'B', 3, "stSchool");
return (0);
}
Run Code Online (Sandbox Code Playgroud)
它打印 B, 66,而不是打印 B, 3, stSchool
我需要知道问题出在哪里。
我预计问题会出现在每个函数中的 va_arg 中,但是根据我对可变参数函数的不太详细的了解,我无法更改某些内容。而且我不想使用开关盒来实现它,以便模块化我的程序。
va_list按值传递给多个函数是无效的。您必须传递一个指向 的指针va_list。
#include <stdio.h>
#include <stdarg.h>
typedef struct formatter {
char spec;
void (*print)(va_list*);
} fmt;
void print_char(va_list *args) {
printf("%c", va_arg(*args, int));
}
void print_int(va_list *args) {
printf("%d", va_arg(*args, int));
}
void print_float(va_list *args) {
printf("%f", va_arg(*args, double));
}
void print_string(va_list *args) {
char *spec = va_arg(*args, char *);
if (spec == NULL) {
printf("(nil)");
return;
}
printf("%s", spec);
}
void print_all(const char *const format, ...) {
fmt f[] = {
{'c', print_char},
{'i', print_int},
{'f', print_float},
{'s', print_string},
{'\0', NULL}};
const char *separator = "";
va_list args;
va_start(args, format);
if (format == NULL) {
return;
}
for (int i = 0; format[i] != '\0'; ++i) {
for (int j = 0; f[j].spec; f++) {
if (f[j].spec == format[i]) {
printf("%s", separator);
f[j].print(&args);
separator = ", ";
break;
}
}
}
printf("\n");
va_end(args);
}
int main(void) {
print_all("cis", 'B', 3, "stSchool");
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
172 次 |
| 最近记录: |