【发布时间】:2021-03-11 23:34:39
【问题描述】:
我想知道是否有一种方法可以循环访问 FILE *ptr 以便获取它的大小。例如:
char *buffer = malloc(512);
FILE *command = popen("pwd","r");
pclose(command);
我想循环*命令输出直到结束并创建一个计数器大小++ 这样我就可以计算出它的大小。 但我不知道如何在这里循环。 如果有人可以请告诉我这是否可能以及如何。 谢谢。
【问题讨论】:
我想知道是否有一种方法可以循环访问 FILE *ptr 以便获取它的大小。例如:
char *buffer = malloc(512);
FILE *command = popen("pwd","r");
pclose(command);
我想循环*命令输出直到结束并创建一个计数器大小++ 这样我就可以计算出它的大小。 但我不知道如何在这里循环。 如果有人可以请告诉我这是否可能以及如何。 谢谢。
【问题讨论】:
您只能从管道中读取一次数据。如果要计算数据量,则需要将其全部存储并计数。比如:
#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
static void * xrealloc(void *buf, size_t num, size_t siz, void *end);
struct string{ char *start, *end; size_t cap; };
static void
push(int c, struct string *b)
{
if( b->start == NULL || b->end >= b->start + b->cap ) {
b->start = xrealloc(b->start, b->cap += 128,
sizeof *b->start, &b->end);
}
*b->end++ = c;
}
int
main(int argc, char **argv)
{
int c;
int text = 1;
char *cmd = argc > 1 ? argv[1] : "pwd";
struct string content = {0};
FILE *command = popen(cmd,"r");
if( command == NULL ) {
perror("pwd");
return EXIT_FAILURE;
}
while( (c = getc(command)) != EOF ){
push(c, &content);
if( ! isprint(c) && ! isspace(c)) {
text = 0;
}
}
printf("%zu bytes\n", content.end - content.start);
if( text ) {
push('\0', &content);
printf("%s", content.start);
}
return 0;
}
static void *
xrealloc(void *buf, size_t num, size_t siz, void *endvp)
{
void **endp = endvp;
ptrdiff_t offset = endp && *endp ? *endp - buf : 0;
buf = realloc(buf, num * siz);
if( buf == NULL ){
perror("realloc");
exit(EXIT_FAILURE);
}
if( endp != NULL ){
*endp = buf + offset;
}
return buf;
}
【讨论】:
*b->end++ = c 有效,因为它将 c 的值放入正确的位置。 c = *b->end++ 无法工作,因为 *b->end 未初始化,因此尝试读取其值是未定义的行为,而 c 是局部变量,因此在从函数返回之前分配它是没有意义的。
struct string *content = {0},因为初始化器右侧的值类型错误。你可以做struct string a; struct string *content = &a。