【问题标题】:Reading long ASCII-files in C用 C 读取长的 ASCII 文件
【发布时间】:2009-10-25 10:08:17
【问题描述】:

在 C 语言中,如果我通过函数 fgetc 从文件中读取一行,可能会出现堆栈溢出。假设有人编写了一个程序,该程序在特定文件的一行中输出一大行 ASCII 数据。如何在我的 C 程序中读取该数据以进行筛选?我知道我只能阅读,一次说 100 个字符,但我不知道如何从特定位置开始阅读。

【问题讨论】:

    标签: c file


    【解决方案1】:

    您可以使用 read() 函数一次读取设定的大小(例如 100 个字节)。你只是继续这样做是一个循环,直到 read() 表明没有什么可以读了。 read() 返回读取的字节数,因此当它返回的字节数少于您请求的字节数时,您就知道您已经完成了。

    【讨论】:

    • Fread 当然允许从特定位置读取。 fread() 将始终从文件的“当前位置”读取(这是特定的,可以通过 fseek 修改)。
    • 当然。但是,没有办法在 fread 中指定当前位置。
    【解决方案2】:

    您可以使用 malloc() 动态分配 char 数组,然后使用 fgetc() 逐字符读取文件。当你到达缓冲区的末尾时,调用 realloc() 来扩展缓冲区,然后继续读取字符。这样,您可能遇到的唯一错误是“内存不足”错误。

    char *buffer = malloc( 200 );
    unsigned int buffer_size = 200;
    unsigned int current = 0;
    char read;
    
    do
    {
        read = fgetc( stream );
        if ( current >= buffer_size - 1 )
        {
            buffer_size += 200;
            buffer = realloc( buffer, buffer_size );
        }
        buffer[current++] = read;
    }
    while ( read != '\n' );
    buffer[current++] = '\0';
    

    (上面代码中缺少:检查 realloc 的返回值以处理内存不足的情况)

    【讨论】:

      【解决方案3】:

      也看mmap()

      mmap 整个文件,您可以将结果视为将整个文件读入数组。 不必分配任何内存。

      无论谁对我投了反对票,我真的很想看看你对为什么 seek&read 比 mmap 更好的解释

      【讨论】:

      • 我没有对你投反对票,但我的反对意见是它不能解决一般问题类。它可以在这种特定情况下工作,但在插座、外部设备等方面存在完全相同的问题,而它不会。鉴于 OP 似乎相对缺乏经验,最好教授最佳实践,而不是建议如果他没有准备好可能会让他感到困惑的事情。
      【解决方案4】:

      请参阅 fseek() 和 ftell()。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-05-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-22
        • 1970-01-01
        • 2016-01-24
        相关资源
        最近更新 更多