arrays - 当长度、元素大小和格式已知时,如何使用 printf 打印 void * 数组?
问题描述
我已经尝试过这种方式。然后在输出中得到垃圾并发现我做错了。
#include "stdlib.h"
#include "stdio.h"
/*
* Prints array from the anonymous array pointer.
*
* Returns 0 on success.
* Return -1 on failure.
*/
int print_array(const void *arr, size_t arr_len,
size_t elem_size, const char *format) {
for (size_t i = 0; i < arr_len; ++i)
if (printf(format, (char *) arr + i * elem_size) < 0)
return -1;
printf("\n");
return 0;
}
// Usage example
int main() {
const int n = 3;
int arr[n];
for (int i = 0; i < n; ++i)
arr[i] = i;
print_array(arr, n, sizeof(int), "%d ");
}
我的代码应该适用于不同的可能类型。类型实际上是在执行开始的某个地方推导出来的,然后使用这个最小描述。这种技巧很好地适用,scanf
因为它需要指向元素而不是元素本身的指针。
需要这种复杂性来符合开闭原则,从而最大限度地减少代码中的开关和条件句的数量。我试图只将实际类型推导集中在一个地方。
我想与 with 相同的事情scanf
应该是可能的,因为printf
它实际上是一个可变参数函数,它可以在运行时获取任何值并解析它们。滥用“stdarg.h”可能会有所帮助。
当然,我希望有不是特定于编译器的解决方案。
解决方案
与其传递格式化字符串,不如传递一个函数来打印它,允许用户做他想做/需要的任何事情来打印实际数据。
int print_array(const void *arr, size_t arr_len, size_t elem_size,
int (*print_elem)(const void *el, void *cookie), // I would add FILE* argument
void *cookie // allow users to pass additional context if they wanna
) {
for (size_t i = 0; i < arr_len; ++i) {
if (print_elem((char*)arr + i * elem_size, cookie) < 0) {
return -1;
}
}
printf("\n");
return 0;
}
int print_int(const void *el, void *cookie) {
return printf("%d", *(int*)el);
}
// print and allow users to pass options
int print_int_with_width(const void *el, void *cookie) {
int width = *(int*)cookie;
return printf("%*d", width, *(int*)el);
}
int arr[5];
int main() {
print_array(arr, 5, sizeof(int), print_int, NULL);
int width = 5;
print_array(arr, 5, sizeof(int), print_int_with_width, &width);
}
推荐阅读
- java - 使用 apache poi 4.1.2 创建工作簿会引发 IndexOutOfBoundsException
- flutter - 如何在 listview Flutter 中使用 showmenu
- javascript - Moment.js,Moment-timezone:在东部时区输入和显示?
- swiftui - 类不符合 Encodable
- python - 在 TensorArray 中为 While_loop 存储可训练值 - tensorflow
- javascript - 显示选定的值
- android - Anychart使用函数作为参数创建图形
- javascript - 减少 Vue 服务的文件数量
- reactjs - 使用 react-router-dom V5.+ 完成操作后重定向
- laravel - Laravel Order By 返回奇怪的顺序