我想知道是否有一种方法可以遍历FILE * ptr以获取其大小,例如:
char *buffer = malloc(512);
FILE *command = popen("pwd","r");
pclose(command);
我想遍历* command输出直到最后,并创建一个计数器size ++,这样我就可以计算其大小。但是我不知道如何在这里循环。如果有人可以,请告诉我这是否可行以及如何实现。谢谢。
你只能从管道读取一次数据。如果要计算数据量,则需要全部存储并计数。就像是:
#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;
}
仅有两个简单的疑问:1-为什么* b-> end ++ = c起作用,但是相反,我的意思是c = * b-> end ++。我知道结果是不同的,但这是两种方式的分配。2-为什么我不能声明结构字符串* content = {0}而不是没有指针的内容;当我使用指针并修改代码以使用content-> something时,它将停止工作。听起来可能很奇怪,但是我仍在学习C语言,有些事情我并不是很了解。顺便说一句,感谢您的快速解答。
*b->end++ = c
之所以起作用,是因为它将c的值放置在正确的位置。c = *b->end++
由于*b->end
未初始化而无法工作,因此尝试读取其值是未定义的行为,并且c是局部变量,因此在从函数返回之前分配它是毫无意义的。您无法声明,
struct string *content = {0}
因为初始化器右侧的值类型错误。你可以做的struct string a; struct string *content = &a
。