使用fgets() - 最有效的内存方式

时间:2015-09-11 21:25:23

标签: c linux memory buffer fgets

在线查看我还没有找到与fgets()字符指针数组(char * restrict s )相关的有效内存分配的确定答案。

简介: char *fgets(char *restrict s, int n, FILE *restrict stream);

查看fgets() - specification

根据我对此规范的理解,您应该根据LINE_MAX - specification中定义的<limits.h>宏进行分配,原因很简单,因为您不知道每行有多少个字符具有

如果我运行 - printf("LINE_MAX BYTES: %d\n", LINE_MAX);,则结果为2048

话虽如此,声明char *line[LINE_MAX] - 或 - char *line[2048]似乎对我来说效率不高,但是,这可能是最好的方式吗?

// PROGRAM

#include <stdio.h>                                                                                                  
#include <limits.h>                                                                                                 
int main(void){                                                                                                     
    char line[LINE_MAX];                                                                                   
    FILE *fp = fopen("file.txt", "r");                                                                          
    while(fgets(line, LINE_MAX + 1, fp)){                                                                           
        printf("%s", line);                                                                               
    }                                                                                                    
    fclose(fp);                                                                                                 
    return(0); 
}  

// FILE(file.txt)

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 

2 个答案:

答案 0 :(得分:3)

除非您的文件具有某些特殊属性,否则分配LINE_MAX字节是最佳方法。虽然你可能在那里浪费了一些记忆,但是在自动记忆中的分配真的很便宜,因为空间正在被保留&#34;超过&#34;已分配&#34;,在大多数现代架构上都有大量硬件支持。

另一方面,如果您知道由于文件格式的行不能超过一定长度MY_LINE,您可以使用MY_LINE+2 * 作为您的改为限制:

char line[MY_LINE+2];

例如,以uuendode格式读取文件的程序每行最多需要62个字符,因此可以定义

#define MY_LINE 62

* 假设您使用的是UNIX,则需要'\n''\0'的空间,因此需要+2部分。如果您使用的是Windows,请执行+3以容纳额外的'\r'字符。

答案 1 :(得分:0)

以下代码:

cleanly compiles
performs error checking

如果一条线太长,则部分线将回显,然后下一次调用fgets()将获得更多的线,这将是echo&#39; d等。不会丢失任何输出,也不会执行任何未定义的行为。

你可以使用&#39; getline()&#39;而不是fgets(),但为什么这么麻烦。使用getline()会使代码更复杂,而不添加任何功能,并且(正如其他人所评论的那样)2048字节的缓冲区在今天很简单。电脑。

如果你真的担心缓冲区大小。以下可以使用一个小到2个字节的缓冲区用于linux / mac(3个字节用于windows / DOS)并且仍能正常工作

#include <stdio.h>
#include <stdlib.h>

#define LINE_MAX (2048)

int main(void)
{
#include <stdio.h>
#include <stdlib.h>

#define LINE_MAX (2048)

int main(void)
{

    char line[LINE_MAX];

    FILE *fp = NULL;
    if( NULL ==( fp = fopen("file.txt", "r") ) )
    {
        perror( "fopen for file.txt for read failed");
        exit( EXIT_FAILURE );
    }

    while( fgets(line, LINE_MAX, fp) )
    {
        printf("%s\n", line);
    }

    fclose(fp);
    return(0);
}

    char line[LINE_MAX];

    FILE *fp = NULL;
    if( NULL ==( fp = fopen("file.txt", "r") ) )
    {
        perror( "fopen for file.txt for read failed");
        exit( EXIT_FAILURE );
    }

    while( fgets(line, LINE_MAX, fp) )
    {
        printf("%s", line);
    }

    fclose(fp);
    return(0);
}