Warm tip: This article is reproduced from serverfault.com, please click

c-如何循环通过文件流

(c - how to loop through File stream)

发布于 2020-11-30 01:09:12

我想知道是否有一种方法可以遍历FILE * ptr以获取其大小,例如:

char *buffer = malloc(512);
FILE *command = popen("pwd","r");
pclose(command);

我想遍历* command输出直到最后,并创建一个计数器size ++,这样我就可以计算其大小。但是我不知道如何在这里循环。如果有人可以,请告诉我这是否可行以及如何实现。谢谢。

Questioner
PedroVLP
Viewed
0
William Pursell 2020-11-30 17:05:04

你只能从管道读取一次数据。如果要计算数据量,则需要全部存储并计数。就像是:

#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;
}