使用 fgets( ) - 内存效率最高的方法

Using fgets( ) - the most memory efficient way

环顾网上,我还没有找到与 fgets() 字符指针数组 (char *restrict s) 相关的有效内存分配方面的明确答案.

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

正在查看 fgets() - specification

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

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

也就是说,声明 char *line[LINE_MAX] - 或 - char *line[2048] 对我来说似乎效率低下,但是,这可能是最好的方法吗?

//程序

#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.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. 

除非您的文件具有某些特殊属性,否则分配 LINE_MAX 字节是最好的方法。虽然你可能在那里浪费了一些内存,但自动内存中的分配确实很便宜,因为 space 比 "allocated" 多 "reserved",大多数现代体系结构都有很多硬件支持。

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

char line[MY_LINE+2];

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

#define MY_LINE 62

* 假设您使用的是 UNIX,对于 '\n''[=17=]',您需要 space,因此 +2部分。如果您在 Windows,请执行 +3 以容纳额外的 '\r' 字符。

以下代码:

cleanly compiles
performs error checking

如果一行太长,部分行将被回显,然后下一次调用 fgets() 将获得更多的行,这将被回显,等等。不会丢失任何输出,也不会执行未定义的行为。

您可以使用 'getline()' 而不是 fgets(),但何必呢。使用 getline() 将使代码更加复杂,而不会添加任何功能,并且(正如其他人所评论的那样)2048 字节的缓冲区在当今的计算机上是微不足道的。

如果您真的担心缓冲区大小。下面的代码可以为 linux/mac 使用小至 2 个字节的缓冲区(windows/DOS 为 3 个字节)并且仍然可以正常工作

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