【问题标题】:how to loop through File stream如何循环文件流
【发布时间】:2021-03-11 23:34:39
【问题描述】:

我想知道是否有一种方法可以循环访问 FILE *ptr 以便获取它的大小。例如:

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

我想循环*命令输出直到结束并创建一个计数器大小++ 这样我就可以计算出它的大小。 但我不知道如何在这里循环。 如果有人可以请告诉我这是否可能以及如何。 谢谢。

【问题讨论】:

    标签: c linux loops unix


    【解决方案1】:

    您只能从管道中读取一次数据。如果要计算数据量,则需要将其全部存储并计数。比如:

    #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-以及为什么我不能声明 struct string *content = {0} 而不是没有指针的内容;当我使用指针并修改代码以使用 content->something 它停止工作。听起来可能很奇怪,但我仍在学习 C 语言,有些东西我不太明白。顺便感谢您的快速回答。
    • *b-&gt;end++ = c 有效,因为它将 c 的值放入正确的位置。 c = *b-&gt;end++ 无法工作,因为 *b-&gt;end 未初始化,因此尝试读取其值是未定义的行为,而 c 是局部变量,因此在从函数返回之前分配它是没有意义的。
    • 您不能声明struct string *content = {0},因为初始化器右侧的值类型错误。你可以做struct string a; struct string *content = &amp;a
    猜你喜欢
    • 1970-01-01
    • 2012-05-10
    • 2019-08-19
    • 2017-04-20
    • 2014-05-19
    • 1970-01-01
    • 2013-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多